13d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3d7b241e6Sjeremylt // 43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 5d7b241e6Sjeremylt // 63d8e8822SJeremy L Thompson // This file is part of CEED: http://github.com/ceed 7d7b241e6Sjeremylt 8ec3da8bcSJed Brown #include <ceed/ceed.h> 9ec3da8bcSJed Brown #include <ceed/backend.h> 103d576824SJeremy L Thompson #include <ceed-impl.h> 113d576824SJeremy L Thompson #include <stdbool.h> 123d576824SJeremy L Thompson #include <stdio.h> 133d576824SJeremy L Thompson #include <string.h> 14d7b241e6Sjeremylt 15dfdf5a53Sjeremylt /// @file 167a982d89SJeremy L. Thompson /// Implementation of CeedOperator interfaces 177a982d89SJeremy L. Thompson 187a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 197a982d89SJeremy L. Thompson /// CeedOperator Library Internal Functions 207a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 217a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorDeveloper 227a982d89SJeremy L. Thompson /// @{ 237a982d89SJeremy L. Thompson 247a982d89SJeremy L. Thompson /** 25e15f9bd0SJeremy L Thompson @brief Check if a CeedOperator Field matches the QFunction Field 26e15f9bd0SJeremy L Thompson 27e15f9bd0SJeremy L Thompson @param[in] ceed Ceed object for error handling 28d1d35e2fSjeremylt @param[in] qf_field QFunction Field matching Operator Field 29e15f9bd0SJeremy L Thompson @param[in] r Operator Field ElemRestriction 30e15f9bd0SJeremy L Thompson @param[in] b Operator Field Basis 31e15f9bd0SJeremy L Thompson 32e15f9bd0SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 33e15f9bd0SJeremy L Thompson 34e15f9bd0SJeremy L Thompson @ref Developer 35e15f9bd0SJeremy L Thompson **/ 36d1d35e2fSjeremylt static int CeedOperatorCheckField(Ceed ceed, CeedQFunctionField qf_field, 37e15f9bd0SJeremy L Thompson CeedElemRestriction r, CeedBasis b) { 38e15f9bd0SJeremy L Thompson int ierr; 39d1d35e2fSjeremylt CeedEvalMode eval_mode = qf_field->eval_mode; 40d1d35e2fSjeremylt CeedInt dim = 1, num_comp = 1, restr_num_comp = 1, size = qf_field->size; 41e15f9bd0SJeremy L Thompson // Restriction 42e15f9bd0SJeremy L Thompson if (r != CEED_ELEMRESTRICTION_NONE) { 43d1d35e2fSjeremylt if (eval_mode == CEED_EVAL_WEIGHT) { 44e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 45e1e9e29dSJed Brown return CeedError(ceed, CEED_ERROR_INCOMPATIBLE, 46e1e9e29dSJed Brown "CEED_ELEMRESTRICTION_NONE should be used " 47e15f9bd0SJeremy L Thompson "for a field with eval mode CEED_EVAL_WEIGHT"); 48e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 49e15f9bd0SJeremy L Thompson } 50d1d35e2fSjeremylt ierr = CeedElemRestrictionGetNumComponents(r, &restr_num_comp); 5178464608Sjeremylt CeedChk(ierr); 52e1e9e29dSJed Brown } 53d1d35e2fSjeremylt if ((r == CEED_ELEMRESTRICTION_NONE) != (eval_mode == CEED_EVAL_WEIGHT)) { 54e1e9e29dSJed Brown // LCOV_EXCL_START 55e1e9e29dSJed Brown return CeedError(ceed, CEED_ERROR_INCOMPATIBLE, 56e1e9e29dSJed Brown "CEED_ELEMRESTRICTION_NONE and CEED_EVAL_WEIGHT " 57e1e9e29dSJed Brown "must be used together."); 58e1e9e29dSJed Brown // LCOV_EXCL_STOP 59e1e9e29dSJed Brown } 60e15f9bd0SJeremy L Thompson // Basis 61e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 62d1d35e2fSjeremylt if (eval_mode == CEED_EVAL_NONE) 638229195eSjeremylt // LCOV_EXCL_START 64e1e9e29dSJed Brown return CeedError(ceed, CEED_ERROR_INCOMPATIBLE, 65d1d35e2fSjeremylt "Field '%s' configured with CEED_EVAL_NONE must " 66d1d35e2fSjeremylt "be used with CEED_BASIS_COLLOCATED", 67d1d35e2fSjeremylt qf_field->field_name); 6841bdf1c9SJeremy L Thompson // LCOV_EXCL_STOP 69e15f9bd0SJeremy L Thompson ierr = CeedBasisGetDimension(b, &dim); CeedChk(ierr); 70d1d35e2fSjeremylt ierr = CeedBasisGetNumComponents(b, &num_comp); CeedChk(ierr); 71d1d35e2fSjeremylt if (r != CEED_ELEMRESTRICTION_NONE && restr_num_comp != num_comp) { 72e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 73e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 74990fdeb6SJeremy L Thompson "Field '%s' of size %" CeedInt_FMT " and EvalMode %s: ElemRestriction " 75990fdeb6SJeremy L Thompson "has %" CeedInt_FMT " components, but Basis has %" CeedInt_FMT " components", 76d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], 77d1d35e2fSjeremylt restr_num_comp, 78d1d35e2fSjeremylt num_comp); 79e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 80e15f9bd0SJeremy L Thompson } 8141bdf1c9SJeremy L Thompson } else if (eval_mode != CEED_EVAL_NONE) { 8241bdf1c9SJeremy L Thompson // LCOV_EXCL_START 8341bdf1c9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPATIBLE, 8441bdf1c9SJeremy L Thompson "Field '%s' configured with %s cannot " 8541bdf1c9SJeremy L Thompson "be used with CEED_BASIS_COLLOCATED", 8641bdf1c9SJeremy L Thompson qf_field->field_name, CeedEvalModes[eval_mode]); 8741bdf1c9SJeremy L Thompson // LCOV_EXCL_STOP 8841bdf1c9SJeremy L Thompson 89e15f9bd0SJeremy L Thompson } 90e15f9bd0SJeremy L Thompson // Field size 91*a0c16c2cSrezgarshakeri CeedInt Q_comp; 92*a0c16c2cSrezgarshakeri ierr = CeedBasisGetNumQuadratureComponents(b, &Q_comp); CeedChk(ierr); 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, 98990fdeb6SJeremy L Thompson "Field '%s' of size %" CeedInt_FMT " and EvalMode %s: ElemRestriction has " 99990fdeb6SJeremy L Thompson CeedInt_FMT " components", 100d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], 101d1d35e2fSjeremylt restr_num_comp); 102e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 103e15f9bd0SJeremy L Thompson break; 104e15f9bd0SJeremy L Thompson case CEED_EVAL_INTERP: 105*a0c16c2cSrezgarshakeri if (size != num_comp*Q_comp) 106e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 107e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 108990fdeb6SJeremy L Thompson "Field '%s' of size %" CeedInt_FMT 109990fdeb6SJeremy L Thompson " and EvalMode %s: ElemRestriction/Basis has " 110990fdeb6SJeremy L Thompson CeedInt_FMT " components", 111d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], 112*a0c16c2cSrezgarshakeri num_comp*Q_comp); 113e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 114e15f9bd0SJeremy L Thompson break; 115e15f9bd0SJeremy L Thompson case CEED_EVAL_GRAD: 116d1d35e2fSjeremylt if (size != num_comp * dim) 117e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 118e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 119990fdeb6SJeremy L Thompson "Field '%s' of size %" CeedInt_FMT " and EvalMode %s in %" CeedInt_FMT 120990fdeb6SJeremy L Thompson " dimensions: " 121990fdeb6SJeremy L Thompson "ElemRestriction/Basis has %" CeedInt_FMT " components", 122d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], dim, 123d1d35e2fSjeremylt num_comp); 124e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 125e15f9bd0SJeremy L Thompson break; 126e15f9bd0SJeremy L Thompson case CEED_EVAL_WEIGHT: 127d1d35e2fSjeremylt // No additional checks required 128e15f9bd0SJeremy L Thompson break; 129e15f9bd0SJeremy L Thompson case CEED_EVAL_DIV: 130*a0c16c2cSrezgarshakeri if (size != num_comp) 131*a0c16c2cSrezgarshakeri // LCOV_EXCL_START 132*a0c16c2cSrezgarshakeri return CeedError(ceed, CEED_ERROR_DIMENSION, 133*a0c16c2cSrezgarshakeri "Field '%s' of size %" CeedInt_FMT 134*a0c16c2cSrezgarshakeri " and EvalMode %s: ElemRestriction/Basis has " 135*a0c16c2cSrezgarshakeri CeedInt_FMT " components", 136*a0c16c2cSrezgarshakeri qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], 137*a0c16c2cSrezgarshakeri num_comp); 138*a0c16c2cSrezgarshakeri // LCOV_EXCL_STOP 139e15f9bd0SJeremy L Thompson break; 140e15f9bd0SJeremy L Thompson case CEED_EVAL_CURL: 141e15f9bd0SJeremy L Thompson // Not implemented 142e15f9bd0SJeremy L Thompson break; 143e15f9bd0SJeremy L Thompson } 144e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1457a982d89SJeremy L. Thompson } 1467a982d89SJeremy L. Thompson 1477a982d89SJeremy L. Thompson /** 1487a982d89SJeremy L. Thompson @brief View a field of a CeedOperator 1497a982d89SJeremy L. Thompson 1507a982d89SJeremy L. Thompson @param[in] field Operator field to view 151d1d35e2fSjeremylt @param[in] qf_field QFunction field (carries field name) 152d1d35e2fSjeremylt @param[in] field_number Number of field being viewed 1534c4400c7SValeria Barra @param[in] sub true indicates sub-operator, which increases indentation; false for top-level operator 154d1d35e2fSjeremylt @param[in] input true for an input field; false for output field 1557a982d89SJeremy L. Thompson @param[in] stream Stream to view to, e.g., stdout 1567a982d89SJeremy L. Thompson 1577a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1587a982d89SJeremy L. Thompson 1597a982d89SJeremy L. Thompson @ref Utility 1607a982d89SJeremy L. Thompson **/ 1617a982d89SJeremy L. Thompson static int CeedOperatorFieldView(CeedOperatorField field, 162d1d35e2fSjeremylt CeedQFunctionField qf_field, 163d1d35e2fSjeremylt CeedInt field_number, bool sub, bool input, 1647a982d89SJeremy L. Thompson FILE *stream) { 1657a982d89SJeremy L. Thompson const char *pre = sub ? " " : ""; 166d1d35e2fSjeremylt const char *in_out = input ? "Input" : "Output"; 1677a982d89SJeremy L. Thompson 168990fdeb6SJeremy L Thompson fprintf(stream, "%s %s field %" CeedInt_FMT ":\n" 1697a982d89SJeremy L. Thompson "%s Name: \"%s\"\n", 170d1d35e2fSjeremylt pre, in_out, field_number, pre, qf_field->field_name); 1717a982d89SJeremy L. Thompson 172990fdeb6SJeremy L Thompson fprintf(stream, "%s Size: %" CeedInt_FMT "\n", pre, qf_field->size); 173f5ebfb90SJeremy L Thompson 174f5ebfb90SJeremy L Thompson fprintf(stream, "%s EvalMode: %s\n", pre, 175f5ebfb90SJeremy L Thompson CeedEvalModes[qf_field->eval_mode]); 176f5ebfb90SJeremy L Thompson 1777a982d89SJeremy L. Thompson if (field->basis == CEED_BASIS_COLLOCATED) 1787a982d89SJeremy L. Thompson fprintf(stream, "%s Collocated basis\n", pre); 1797a982d89SJeremy L. Thompson 1807a982d89SJeremy L. Thompson if (field->vec == CEED_VECTOR_ACTIVE) 1817a982d89SJeremy L. Thompson fprintf(stream, "%s Active vector\n", pre); 1827a982d89SJeremy L. Thompson else if (field->vec == CEED_VECTOR_NONE) 1837a982d89SJeremy L. Thompson fprintf(stream, "%s No vector\n", pre); 184f5ebfb90SJeremy L Thompson 185e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1867a982d89SJeremy L. Thompson } 1877a982d89SJeremy L. Thompson 1887a982d89SJeremy L. Thompson /** 1897a982d89SJeremy L. Thompson @brief View a single CeedOperator 1907a982d89SJeremy L. Thompson 1917a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 1927a982d89SJeremy L. Thompson @param[in] sub Boolean flag for sub-operator 1937a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 1947a982d89SJeremy L. Thompson 1957a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 1967a982d89SJeremy L. Thompson 1977a982d89SJeremy L. Thompson @ref Utility 1987a982d89SJeremy L. Thompson **/ 1997a982d89SJeremy L. Thompson int CeedOperatorSingleView(CeedOperator op, bool sub, FILE *stream) { 2007a982d89SJeremy L. Thompson int ierr; 2017a982d89SJeremy L. Thompson const char *pre = sub ? " " : ""; 2027a982d89SJeremy L. Thompson 203381e6593SJeremy L Thompson CeedInt num_elem, num_qpts; 204381e6593SJeremy L Thompson ierr = CeedOperatorGetNumElements(op, &num_elem); CeedChk(ierr); 205381e6593SJeremy L Thompson ierr = CeedOperatorGetNumQuadraturePoints(op, &num_qpts); CeedChk(ierr); 206381e6593SJeremy L Thompson 20778464608Sjeremylt CeedInt total_fields = 0; 20878464608Sjeremylt ierr = CeedOperatorGetNumArgs(op, &total_fields); CeedChk(ierr); 209990fdeb6SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " elements with %" CeedInt_FMT 210990fdeb6SJeremy L Thompson " quadrature points each\n", 211381e6593SJeremy L Thompson pre, num_elem, num_qpts); 2127a982d89SJeremy L. Thompson 213990fdeb6SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " field%s\n", pre, total_fields, 21478464608Sjeremylt total_fields>1 ? "s" : ""); 2157a982d89SJeremy L. Thompson 216990fdeb6SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " input field%s:\n", pre, 217990fdeb6SJeremy L Thompson op->qf->num_input_fields, 218d1d35e2fSjeremylt op->qf->num_input_fields>1 ? "s" : ""); 219d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_input_fields; i++) { 220d1d35e2fSjeremylt ierr = CeedOperatorFieldView(op->input_fields[i], op->qf->input_fields[i], 2217a982d89SJeremy L. Thompson i, sub, 1, stream); CeedChk(ierr); 2227a982d89SJeremy L. Thompson } 2237a982d89SJeremy L. Thompson 224990fdeb6SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " output field%s:\n", pre, 225990fdeb6SJeremy L Thompson op->qf->num_output_fields, 226d1d35e2fSjeremylt op->qf->num_output_fields>1 ? "s" : ""); 227d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_output_fields; i++) { 228d1d35e2fSjeremylt ierr = CeedOperatorFieldView(op->output_fields[i], op->qf->output_fields[i], 2297a982d89SJeremy L. Thompson i, sub, 0, stream); CeedChk(ierr); 2307a982d89SJeremy L. Thompson } 231e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2327a982d89SJeremy L. Thompson } 2337a982d89SJeremy L. Thompson 234d99fa3c5SJeremy L Thompson /** 2350f60e0a8SJeremy L Thompson @brief Find the active vector basis for a non-composite CeedOperator 236eaf62fffSJeremy L Thompson 237eaf62fffSJeremy L Thompson @param[in] op CeedOperator to find active basis for 2380f60e0a8SJeremy L Thompson @param[out] active_basis Basis for active input vector or NULL for composite operator 239eaf62fffSJeremy L Thompson 240eaf62fffSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 241eaf62fffSJeremy L Thompson 242eaf62fffSJeremy L Thompson @ ref Developer 243eaf62fffSJeremy L Thompson **/ 244eaf62fffSJeremy L Thompson int CeedOperatorGetActiveBasis(CeedOperator op, CeedBasis *active_basis) { 245eaf62fffSJeremy L Thompson *active_basis = NULL; 2460f60e0a8SJeremy L Thompson if (op->is_composite) return CEED_ERROR_SUCCESS; 24792ae7e47SJeremy L Thompson for (CeedInt i = 0; i < op->qf->num_input_fields; i++) 248eaf62fffSJeremy L Thompson if (op->input_fields[i]->vec == CEED_VECTOR_ACTIVE) { 249eaf62fffSJeremy L Thompson *active_basis = op->input_fields[i]->basis; 250eaf62fffSJeremy L Thompson break; 251eaf62fffSJeremy L Thompson } 252eaf62fffSJeremy L Thompson 253eaf62fffSJeremy L Thompson if (!*active_basis) { 254eaf62fffSJeremy L Thompson // LCOV_EXCL_START 255eaf62fffSJeremy L Thompson int ierr; 256eaf62fffSJeremy L Thompson Ceed ceed; 257eaf62fffSJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 258eaf62fffSJeremy L Thompson return CeedError(ceed, CEED_ERROR_MINOR, 259eaf62fffSJeremy L Thompson "No active CeedBasis found"); 260eaf62fffSJeremy L Thompson // LCOV_EXCL_STOP 261eaf62fffSJeremy L Thompson } 262eaf62fffSJeremy L Thompson return CEED_ERROR_SUCCESS; 263eaf62fffSJeremy L Thompson } 264eaf62fffSJeremy L Thompson 265eaf62fffSJeremy L Thompson /** 2660f60e0a8SJeremy L Thompson @brief Find the active vector ElemRestriction for a non-composite CeedOperator 267e2f04181SAndrew T. Barker 268e2f04181SAndrew T. Barker @param[in] op CeedOperator to find active basis for 2690f60e0a8SJeremy L Thompson @param[out] active_rstr ElemRestriction for active input vector or NULL for composite operator 270e2f04181SAndrew T. Barker 271e2f04181SAndrew T. Barker @return An error code: 0 - success, otherwise - failure 272e2f04181SAndrew T. Barker 273e2f04181SAndrew T. Barker @ref Utility 274e2f04181SAndrew T. Barker **/ 275eaf62fffSJeremy L Thompson int CeedOperatorGetActiveElemRestriction(CeedOperator op, 276d1d35e2fSjeremylt CeedElemRestriction *active_rstr) { 277d1d35e2fSjeremylt *active_rstr = NULL; 2780f60e0a8SJeremy L Thompson if (op->is_composite) return CEED_ERROR_SUCCESS; 27992ae7e47SJeremy L Thompson for (CeedInt i = 0; i < op->qf->num_input_fields; i++) 280d1d35e2fSjeremylt if (op->input_fields[i]->vec == CEED_VECTOR_ACTIVE) { 281d1d35e2fSjeremylt *active_rstr = op->input_fields[i]->elem_restr; 282e2f04181SAndrew T. Barker break; 283e2f04181SAndrew T. Barker } 284e2f04181SAndrew T. Barker 285d1d35e2fSjeremylt if (!*active_rstr) { 286e2f04181SAndrew T. Barker // LCOV_EXCL_START 287e2f04181SAndrew T. Barker int ierr; 288e2f04181SAndrew T. Barker Ceed ceed; 289e2f04181SAndrew T. Barker ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 290e2f04181SAndrew T. Barker return CeedError(ceed, CEED_ERROR_INCOMPLETE, 291eaf62fffSJeremy L Thompson "No active CeedElemRestriction found"); 292e2f04181SAndrew T. Barker // LCOV_EXCL_STOP 293e2f04181SAndrew T. Barker } 294e2f04181SAndrew T. Barker return CEED_ERROR_SUCCESS; 295e2f04181SAndrew T. Barker } 296e2f04181SAndrew T. Barker 297d8dd9a91SJeremy L Thompson /** 298d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field value of the specified type. 299d8dd9a91SJeremy L Thompson For composite operators, the value is set in all 300d8dd9a91SJeremy L Thompson sub-operator QFunctionContexts that have a matching `field_name`. 301d8dd9a91SJeremy L Thompson A non-zero error code is returned for single operators 302d8dd9a91SJeremy L Thompson that do not have a matching field of the same type or composite 303d8dd9a91SJeremy L Thompson operators that do not have any field of a matching type. 304d8dd9a91SJeremy L Thompson 305d8dd9a91SJeremy L Thompson @param op CeedOperator 3063668ca4bSJeremy L Thompson @param field_label Label of field to set 307d8dd9a91SJeremy L Thompson @param field_type Type of field to set 308d8dd9a91SJeremy L Thompson @param value Value to set 309d8dd9a91SJeremy L Thompson 310d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 311d8dd9a91SJeremy L Thompson 312d8dd9a91SJeremy L Thompson @ref User 313d8dd9a91SJeremy L Thompson **/ 314d8dd9a91SJeremy L Thompson static int CeedOperatorContextSetGeneric(CeedOperator op, 3153668ca4bSJeremy L Thompson CeedContextFieldLabel field_label, CeedContextFieldType field_type, 3163668ca4bSJeremy L Thompson void *value) { 317d8dd9a91SJeremy L Thompson int ierr; 318d8dd9a91SJeremy L Thompson 3193668ca4bSJeremy L Thompson if (!field_label) 3203668ca4bSJeremy L Thompson // LCOV_EXCL_START 3213668ca4bSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_UNSUPPORTED, 3223668ca4bSJeremy L Thompson "Invalid field label"); 3233668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 3243668ca4bSJeremy L Thompson 3253668ca4bSJeremy L Thompson bool is_composite = false; 326d8dd9a91SJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 327d8dd9a91SJeremy L Thompson if (is_composite) { 328d8dd9a91SJeremy L Thompson CeedInt num_sub; 329d8dd9a91SJeremy L Thompson CeedOperator *sub_operators; 330d8dd9a91SJeremy L Thompson 331d8dd9a91SJeremy L Thompson ierr = CeedOperatorGetNumSub(op, &num_sub); CeedChk(ierr); 332d8dd9a91SJeremy L Thompson ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 3333668ca4bSJeremy L Thompson if (num_sub != field_label->num_sub_labels) 3343668ca4bSJeremy L Thompson // LCOV_EXCL_START 3353668ca4bSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_UNSUPPORTED, 3363668ca4bSJeremy L Thompson "ContextLabel does not correspond to composite operator.\n" 3373668ca4bSJeremy L Thompson "Use CeedOperatorGetContextFieldLabel()."); 3383668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 339d8dd9a91SJeremy L Thompson 340d8dd9a91SJeremy L Thompson for (CeedInt i = 0; i < num_sub; i++) { 341d8dd9a91SJeremy L Thompson // Try every sub-operator, ok if some sub-operators do not have field 3423668ca4bSJeremy L Thompson if (field_label->sub_labels[i] && sub_operators[i]->qf->ctx) { 3433668ca4bSJeremy L Thompson ierr = CeedQFunctionContextSetGeneric(sub_operators[i]->qf->ctx, 3443668ca4bSJeremy L Thompson field_label->sub_labels[i], 3453668ca4bSJeremy L Thompson field_type, value); CeedChk(ierr); 346d8dd9a91SJeremy L Thompson } 347d8dd9a91SJeremy L Thompson } 348d8dd9a91SJeremy L Thompson } else { 349d8dd9a91SJeremy L Thompson if (!op->qf->ctx) 350d8dd9a91SJeremy L Thompson // LCOV_EXCL_START 351d8dd9a91SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_UNSUPPORTED, 352d8dd9a91SJeremy L Thompson "QFunction does not have context data"); 353d8dd9a91SJeremy L Thompson // LCOV_EXCL_STOP 354d8dd9a91SJeremy L Thompson 3553668ca4bSJeremy L Thompson ierr = CeedQFunctionContextSetGeneric(op->qf->ctx, field_label, 3563668ca4bSJeremy L Thompson field_type, value); CeedChk(ierr); 357d8dd9a91SJeremy L Thompson } 358d8dd9a91SJeremy L Thompson 359d8dd9a91SJeremy L Thompson return CEED_ERROR_SUCCESS; 360d8dd9a91SJeremy L Thompson } 361d8dd9a91SJeremy L Thompson 3627a982d89SJeremy L. Thompson /// @} 3637a982d89SJeremy L. Thompson 3647a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3657a982d89SJeremy L. Thompson /// CeedOperator Backend API 3667a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3677a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorBackend 3687a982d89SJeremy L. Thompson /// @{ 3697a982d89SJeremy L. Thompson 3707a982d89SJeremy L. Thompson /** 3717a982d89SJeremy L. Thompson @brief Get the number of arguments associated with a CeedOperator 3727a982d89SJeremy L. Thompson 3737a982d89SJeremy L. Thompson @param op CeedOperator 374d1d35e2fSjeremylt @param[out] num_args Variable to store vector number of arguments 3757a982d89SJeremy L. Thompson 3767a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3777a982d89SJeremy L. Thompson 3787a982d89SJeremy L. Thompson @ref Backend 3797a982d89SJeremy L. Thompson **/ 3807a982d89SJeremy L. Thompson 381d1d35e2fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *num_args) { 382f04ea552SJeremy L Thompson if (op->is_composite) 3837a982d89SJeremy L. Thompson // LCOV_EXCL_START 384e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 385e15f9bd0SJeremy L Thompson "Not defined for composite operators"); 3867a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 3877a982d89SJeremy L. Thompson 388d1d35e2fSjeremylt *num_args = op->num_fields; 389e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3907a982d89SJeremy L. Thompson } 3917a982d89SJeremy L. Thompson 3927a982d89SJeremy L. Thompson /** 3937a982d89SJeremy L. Thompson @brief Get the setup status of a CeedOperator 3947a982d89SJeremy L. Thompson 3957a982d89SJeremy L. Thompson @param op CeedOperator 396d1d35e2fSjeremylt @param[out] is_setup_done Variable to store setup status 3977a982d89SJeremy L. Thompson 3987a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3997a982d89SJeremy L. Thompson 4007a982d89SJeremy L. Thompson @ref Backend 4017a982d89SJeremy L. Thompson **/ 4027a982d89SJeremy L. Thompson 403d1d35e2fSjeremylt int CeedOperatorIsSetupDone(CeedOperator op, bool *is_setup_done) { 404f04ea552SJeremy L Thompson *is_setup_done = op->is_backend_setup; 405e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4067a982d89SJeremy L. Thompson } 4077a982d89SJeremy L. Thompson 4087a982d89SJeremy L. Thompson /** 4097a982d89SJeremy L. Thompson @brief Get the QFunction associated with a CeedOperator 4107a982d89SJeremy L. Thompson 4117a982d89SJeremy L. Thompson @param op CeedOperator 4127a982d89SJeremy L. Thompson @param[out] qf Variable to store QFunction 4137a982d89SJeremy L. Thompson 4147a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4157a982d89SJeremy L. Thompson 4167a982d89SJeremy L. Thompson @ref Backend 4177a982d89SJeremy L. Thompson **/ 4187a982d89SJeremy L. Thompson 4197a982d89SJeremy L. Thompson int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 420f04ea552SJeremy L Thompson if (op->is_composite) 4217a982d89SJeremy L. Thompson // LCOV_EXCL_START 422e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 423e15f9bd0SJeremy L Thompson "Not defined for composite operator"); 4247a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4257a982d89SJeremy L. Thompson 4267a982d89SJeremy L. Thompson *qf = op->qf; 427e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4287a982d89SJeremy L. Thompson } 4297a982d89SJeremy L. Thompson 4307a982d89SJeremy L. Thompson /** 431c04a41a7SJeremy L Thompson @brief Get a boolean value indicating if the CeedOperator is composite 432c04a41a7SJeremy L Thompson 433c04a41a7SJeremy L Thompson @param op CeedOperator 434d1d35e2fSjeremylt @param[out] is_composite Variable to store composite status 435c04a41a7SJeremy L Thompson 436c04a41a7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 437c04a41a7SJeremy L Thompson 438c04a41a7SJeremy L Thompson @ref Backend 439c04a41a7SJeremy L Thompson **/ 440c04a41a7SJeremy L Thompson 441d1d35e2fSjeremylt int CeedOperatorIsComposite(CeedOperator op, bool *is_composite) { 442f04ea552SJeremy L Thompson *is_composite = op->is_composite; 443e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 444c04a41a7SJeremy L Thompson } 445c04a41a7SJeremy L Thompson 446c04a41a7SJeremy L Thompson /** 447d1d35e2fSjeremylt @brief Get the number of sub_operators associated with a CeedOperator 4487a982d89SJeremy L. Thompson 4497a982d89SJeremy L. Thompson @param op CeedOperator 450d1d35e2fSjeremylt @param[out] num_suboperators Variable to store number of sub_operators 4517a982d89SJeremy L. Thompson 4527a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4537a982d89SJeremy L. Thompson 4547a982d89SJeremy L. Thompson @ref Backend 4557a982d89SJeremy L. Thompson **/ 4567a982d89SJeremy L. Thompson 457d1d35e2fSjeremylt int CeedOperatorGetNumSub(CeedOperator op, CeedInt *num_suboperators) { 458f04ea552SJeremy L Thompson if (!op->is_composite) 4597a982d89SJeremy L. Thompson // LCOV_EXCL_START 460e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, "Not a composite operator"); 4617a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4627a982d89SJeremy L. Thompson 463d1d35e2fSjeremylt *num_suboperators = op->num_suboperators; 464e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4657a982d89SJeremy L. Thompson } 4667a982d89SJeremy L. Thompson 4677a982d89SJeremy L. Thompson /** 468d1d35e2fSjeremylt @brief Get the list of sub_operators associated with a CeedOperator 4697a982d89SJeremy L. Thompson 4707a982d89SJeremy L. Thompson @param op CeedOperator 471d1d35e2fSjeremylt @param[out] sub_operators Variable to store list of sub_operators 4727a982d89SJeremy L. Thompson 4737a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4747a982d89SJeremy L. Thompson 4757a982d89SJeremy L. Thompson @ref Backend 4767a982d89SJeremy L. Thompson **/ 4777a982d89SJeremy L. Thompson 478d1d35e2fSjeremylt int CeedOperatorGetSubList(CeedOperator op, CeedOperator **sub_operators) { 479f04ea552SJeremy L Thompson if (!op->is_composite) 4807a982d89SJeremy L. Thompson // LCOV_EXCL_START 481e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, "Not a composite operator"); 4827a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4837a982d89SJeremy L. Thompson 484d1d35e2fSjeremylt *sub_operators = op->sub_operators; 485e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4867a982d89SJeremy L. Thompson } 4877a982d89SJeremy L. Thompson 4887a982d89SJeremy L. Thompson /** 4897a982d89SJeremy L. Thompson @brief Get the backend data of a CeedOperator 4907a982d89SJeremy L. Thompson 4917a982d89SJeremy L. Thompson @param op CeedOperator 4927a982d89SJeremy L. Thompson @param[out] data Variable to store data 4937a982d89SJeremy L. Thompson 4947a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4957a982d89SJeremy L. Thompson 4967a982d89SJeremy L. Thompson @ref Backend 4977a982d89SJeremy L. Thompson **/ 4987a982d89SJeremy L. Thompson 499777ff853SJeremy L Thompson int CeedOperatorGetData(CeedOperator op, void *data) { 500777ff853SJeremy L Thompson *(void **)data = op->data; 501e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5027a982d89SJeremy L. Thompson } 5037a982d89SJeremy L. Thompson 5047a982d89SJeremy L. Thompson /** 5057a982d89SJeremy L. Thompson @brief Set the backend data of a CeedOperator 5067a982d89SJeremy L. Thompson 5077a982d89SJeremy L. Thompson @param[out] op CeedOperator 5087a982d89SJeremy L. Thompson @param data Data to set 5097a982d89SJeremy L. Thompson 5107a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5117a982d89SJeremy L. Thompson 5127a982d89SJeremy L. Thompson @ref Backend 5137a982d89SJeremy L. Thompson **/ 5147a982d89SJeremy L. Thompson 515777ff853SJeremy L Thompson int CeedOperatorSetData(CeedOperator op, void *data) { 516777ff853SJeremy L Thompson op->data = data; 517e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5187a982d89SJeremy L. Thompson } 5197a982d89SJeremy L. Thompson 5207a982d89SJeremy L. Thompson /** 52134359f16Sjeremylt @brief Increment the reference counter for a CeedOperator 52234359f16Sjeremylt 52334359f16Sjeremylt @param op CeedOperator to increment the reference counter 52434359f16Sjeremylt 52534359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 52634359f16Sjeremylt 52734359f16Sjeremylt @ref Backend 52834359f16Sjeremylt **/ 5299560d06aSjeremylt int CeedOperatorReference(CeedOperator op) { 53034359f16Sjeremylt op->ref_count++; 53134359f16Sjeremylt return CEED_ERROR_SUCCESS; 53234359f16Sjeremylt } 53334359f16Sjeremylt 53434359f16Sjeremylt /** 5357a982d89SJeremy L. Thompson @brief Set the setup flag of a CeedOperator to True 5367a982d89SJeremy L. Thompson 5377a982d89SJeremy L. Thompson @param op CeedOperator 5387a982d89SJeremy L. Thompson 5397a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5407a982d89SJeremy L. Thompson 5417a982d89SJeremy L. Thompson @ref Backend 5427a982d89SJeremy L. Thompson **/ 5437a982d89SJeremy L. Thompson 5447a982d89SJeremy L. Thompson int CeedOperatorSetSetupDone(CeedOperator op) { 545f04ea552SJeremy L Thompson op->is_backend_setup = true; 546e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5477a982d89SJeremy L. Thompson } 5487a982d89SJeremy L. Thompson 5497a982d89SJeremy L. Thompson /// @} 5507a982d89SJeremy L. Thompson 5517a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5527a982d89SJeremy L. Thompson /// CeedOperator Public API 5537a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5547a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorUser 555dfdf5a53Sjeremylt /// @{ 556d7b241e6Sjeremylt 557d7b241e6Sjeremylt /** 5580219ea01SJeremy L Thompson @brief Create a CeedOperator and associate a CeedQFunction. A CeedBasis and 5590219ea01SJeremy L Thompson CeedElemRestriction can be associated with CeedQFunction fields with 5600219ea01SJeremy L Thompson \ref CeedOperatorSetField. 561d7b241e6Sjeremylt 562b11c1e72Sjeremylt @param ceed A Ceed object where the CeedOperator will be created 563d7b241e6Sjeremylt @param qf QFunction defining the action of the operator at quadrature points 56434138859Sjeremylt @param dqf QFunction defining the action of the Jacobian of @a qf (or 5654cc79fe7SJed Brown @ref CEED_QFUNCTION_NONE) 566d7b241e6Sjeremylt @param dqfT QFunction defining the action of the transpose of the Jacobian 5674cc79fe7SJed Brown of @a qf (or @ref CEED_QFUNCTION_NONE) 568b11c1e72Sjeremylt @param[out] op Address of the variable where the newly created 569b11c1e72Sjeremylt CeedOperator will be stored 570b11c1e72Sjeremylt 571b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 572dfdf5a53Sjeremylt 5737a982d89SJeremy L. Thompson @ref User 574d7b241e6Sjeremylt */ 575d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, 576d7b241e6Sjeremylt CeedQFunction dqfT, CeedOperator *op) { 577d7b241e6Sjeremylt int ierr; 578d7b241e6Sjeremylt 5795fe0d4faSjeremylt if (!ceed->OperatorCreate) { 5805fe0d4faSjeremylt Ceed delegate; 581aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 5825fe0d4faSjeremylt 5835fe0d4faSjeremylt if (!delegate) 584c042f62fSJeremy L Thompson // LCOV_EXCL_START 585e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 586e15f9bd0SJeremy L Thompson "Backend does not support OperatorCreate"); 587c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 5885fe0d4faSjeremylt 5895fe0d4faSjeremylt ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr); 590e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5915fe0d4faSjeremylt } 5925fe0d4faSjeremylt 593b3b7035fSJeremy L Thompson if (!qf || qf == CEED_QFUNCTION_NONE) 594b3b7035fSJeremy L Thompson // LCOV_EXCL_START 595e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_MINOR, 596e15f9bd0SJeremy L Thompson "Operator must have a valid QFunction."); 597b3b7035fSJeremy L Thompson // LCOV_EXCL_STOP 598d7b241e6Sjeremylt ierr = CeedCalloc(1, op); CeedChk(ierr); 599d7b241e6Sjeremylt (*op)->ceed = ceed; 6009560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 601d1d35e2fSjeremylt (*op)->ref_count = 1; 602d7b241e6Sjeremylt (*op)->qf = qf; 6032b104005SJeremy L Thompson (*op)->input_size = -1; 6042b104005SJeremy L Thompson (*op)->output_size = -1; 6059560d06aSjeremylt ierr = CeedQFunctionReference(qf); CeedChk(ierr); 606442e7f0bSjeremylt if (dqf && dqf != CEED_QFUNCTION_NONE) { 607d7b241e6Sjeremylt (*op)->dqf = dqf; 6089560d06aSjeremylt ierr = CeedQFunctionReference(dqf); CeedChk(ierr); 609442e7f0bSjeremylt } 610442e7f0bSjeremylt if (dqfT && dqfT != CEED_QFUNCTION_NONE) { 611d7b241e6Sjeremylt (*op)->dqfT = dqfT; 6129560d06aSjeremylt ierr = CeedQFunctionReference(dqfT); CeedChk(ierr); 613442e7f0bSjeremylt } 614480fae85SJeremy L Thompson ierr = CeedQFunctionAssemblyDataCreate(ceed, &(*op)->qf_assembled); 615480fae85SJeremy L Thompson CeedChk(ierr); 616bf4cb664SJeremy L Thompson ierr = CeedCalloc(CEED_FIELD_MAX, &(*op)->input_fields); CeedChk(ierr); 617bf4cb664SJeremy L Thompson ierr = CeedCalloc(CEED_FIELD_MAX, &(*op)->output_fields); CeedChk(ierr); 618d7b241e6Sjeremylt ierr = ceed->OperatorCreate(*op); CeedChk(ierr); 619e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 620d7b241e6Sjeremylt } 621d7b241e6Sjeremylt 622d7b241e6Sjeremylt /** 62352d6035fSJeremy L Thompson @brief Create an operator that composes the action of several operators 62452d6035fSJeremy L Thompson 62552d6035fSJeremy L Thompson @param ceed A Ceed object where the CeedOperator will be created 62652d6035fSJeremy L Thompson @param[out] op Address of the variable where the newly created 62752d6035fSJeremy L Thompson Composite CeedOperator will be stored 62852d6035fSJeremy L Thompson 62952d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 63052d6035fSJeremy L Thompson 6317a982d89SJeremy L. Thompson @ref User 63252d6035fSJeremy L Thompson */ 63352d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) { 63452d6035fSJeremy L Thompson int ierr; 63552d6035fSJeremy L Thompson 63652d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 63752d6035fSJeremy L Thompson Ceed delegate; 638aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 63952d6035fSJeremy L Thompson 640250756a7Sjeremylt if (delegate) { 64152d6035fSJeremy L Thompson ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr); 642e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 64352d6035fSJeremy L Thompson } 644250756a7Sjeremylt } 64552d6035fSJeremy L Thompson 64652d6035fSJeremy L Thompson ierr = CeedCalloc(1, op); CeedChk(ierr); 64752d6035fSJeremy L Thompson (*op)->ceed = ceed; 6489560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 649f04ea552SJeremy L Thompson (*op)->is_composite = true; 650bf4cb664SJeremy L Thompson ierr = CeedCalloc(CEED_COMPOSITE_MAX, &(*op)->sub_operators); CeedChk(ierr); 6512b104005SJeremy L Thompson (*op)->input_size = -1; 6522b104005SJeremy L Thompson (*op)->output_size = -1; 653250756a7Sjeremylt 654250756a7Sjeremylt if (ceed->CompositeOperatorCreate) { 65552d6035fSJeremy L Thompson ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr); 656250756a7Sjeremylt } 657e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 65852d6035fSJeremy L Thompson } 65952d6035fSJeremy L Thompson 66052d6035fSJeremy L Thompson /** 6619560d06aSjeremylt @brief Copy the pointer to a CeedOperator. Both pointers should 6629560d06aSjeremylt be destroyed with `CeedOperatorDestroy()`; 6639560d06aSjeremylt Note: If `*op_copy` is non-NULL, then it is assumed that 6649560d06aSjeremylt `*op_copy` is a pointer to a CeedOperator. This 6659560d06aSjeremylt CeedOperator will be destroyed if `*op_copy` is the only 6669560d06aSjeremylt reference to this CeedOperator. 6679560d06aSjeremylt 6689560d06aSjeremylt @param op CeedOperator to copy reference to 6699560d06aSjeremylt @param[out] op_copy Variable to store copied reference 6709560d06aSjeremylt 6719560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 6729560d06aSjeremylt 6739560d06aSjeremylt @ref User 6749560d06aSjeremylt **/ 6759560d06aSjeremylt int CeedOperatorReferenceCopy(CeedOperator op, CeedOperator *op_copy) { 6769560d06aSjeremylt int ierr; 6779560d06aSjeremylt 6789560d06aSjeremylt ierr = CeedOperatorReference(op); CeedChk(ierr); 6799560d06aSjeremylt ierr = CeedOperatorDestroy(op_copy); CeedChk(ierr); 6809560d06aSjeremylt *op_copy = op; 6819560d06aSjeremylt return CEED_ERROR_SUCCESS; 6829560d06aSjeremylt } 6839560d06aSjeremylt 6849560d06aSjeremylt /** 685b11c1e72Sjeremylt @brief Provide a field to a CeedOperator for use by its CeedQFunction 686d7b241e6Sjeremylt 687d7b241e6Sjeremylt This function is used to specify both active and passive fields to a 688d7b241e6Sjeremylt CeedOperator. For passive fields, a vector @arg v must be provided. Passive 689d7b241e6Sjeremylt fields can inputs or outputs (updated in-place when operator is applied). 690d7b241e6Sjeremylt 691d7b241e6Sjeremylt Active fields must be specified using this function, but their data (in a 692d7b241e6Sjeremylt CeedVector) is passed in CeedOperatorApply(). There can be at most one active 693979e564eSJames Wright input CeedVector and at most one active output CeedVector passed to 694979e564eSJames Wright CeedOperatorApply(). 695d7b241e6Sjeremylt 6968c91a0c9SJeremy L Thompson @param op CeedOperator on which to provide the field 697d1d35e2fSjeremylt @param field_name Name of the field (to be matched with the name used by 6988795c945Sjeremylt CeedQFunction) 699b11c1e72Sjeremylt @param r CeedElemRestriction 7004cc79fe7SJed Brown @param b CeedBasis in which the field resides or @ref CEED_BASIS_COLLOCATED 701b11c1e72Sjeremylt if collocated with quadrature points 7024cc79fe7SJed Brown @param v CeedVector to be used by CeedOperator or @ref CEED_VECTOR_ACTIVE 7034cc79fe7SJed Brown if field is active or @ref CEED_VECTOR_NONE if using 7044cc79fe7SJed Brown @ref CEED_EVAL_WEIGHT in the QFunction 705b11c1e72Sjeremylt 706b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 707dfdf5a53Sjeremylt 7087a982d89SJeremy L. Thompson @ref User 709b11c1e72Sjeremylt **/ 710d1d35e2fSjeremylt int CeedOperatorSetField(CeedOperator op, const char *field_name, 711a8d32208Sjeremylt CeedElemRestriction r, CeedBasis b, CeedVector v) { 712d7b241e6Sjeremylt int ierr; 713f04ea552SJeremy L Thompson if (op->is_composite) 714c042f62fSJeremy L Thompson // LCOV_EXCL_START 715e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 716e15f9bd0SJeremy L Thompson "Cannot add field to composite operator."); 717c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 718f04ea552SJeremy L Thompson if (op->is_immutable) 719f04ea552SJeremy L Thompson // LCOV_EXCL_START 720f04ea552SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 721f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 722f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 7238b067b84SJed Brown if (!r) 724c042f62fSJeremy L Thompson // LCOV_EXCL_START 725e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 726c042f62fSJeremy L Thompson "ElemRestriction r for field \"%s\" must be non-NULL.", 727d1d35e2fSjeremylt field_name); 728c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 7298b067b84SJed Brown if (!b) 730c042f62fSJeremy L Thompson // LCOV_EXCL_START 731e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 732e15f9bd0SJeremy L Thompson "Basis b for field \"%s\" must be non-NULL.", 733d1d35e2fSjeremylt field_name); 734c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 7358b067b84SJed Brown if (!v) 736c042f62fSJeremy L Thompson // LCOV_EXCL_START 737e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 738e15f9bd0SJeremy L Thompson "Vector v for field \"%s\" must be non-NULL.", 739d1d35e2fSjeremylt field_name); 740c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 74152d6035fSJeremy L Thompson 742d1d35e2fSjeremylt CeedInt num_elem; 743d1d35e2fSjeremylt ierr = CeedElemRestrictionGetNumElements(r, &num_elem); CeedChk(ierr); 744d1d35e2fSjeremylt if (r != CEED_ELEMRESTRICTION_NONE && op->has_restriction && 745d1d35e2fSjeremylt op->num_elem != num_elem) 746c042f62fSJeremy L Thompson // LCOV_EXCL_START 747e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_DIMENSION, 748990fdeb6SJeremy L Thompson "ElemRestriction with %" CeedInt_FMT " elements incompatible with prior " 749990fdeb6SJeremy L Thompson CeedInt_FMT " elements", num_elem, op->num_elem); 750c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 751d7b241e6Sjeremylt 75278464608Sjeremylt CeedInt num_qpts = 0; 753e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 754d1d35e2fSjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &num_qpts); CeedChk(ierr); 755d1d35e2fSjeremylt if (op->num_qpts && op->num_qpts != num_qpts) 756c042f62fSJeremy L Thompson // LCOV_EXCL_START 757e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_DIMENSION, 758990fdeb6SJeremy L Thompson "Basis with %" CeedInt_FMT " quadrature points " 759990fdeb6SJeremy L Thompson "incompatible with prior %" CeedInt_FMT " points", num_qpts, 760d1d35e2fSjeremylt op->num_qpts); 761c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 762d7b241e6Sjeremylt } 763d1d35e2fSjeremylt CeedQFunctionField qf_field; 764d1d35e2fSjeremylt CeedOperatorField *op_field; 7652b104005SJeremy L Thompson bool is_input = true; 766d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_input_fields; i++) { 767d1d35e2fSjeremylt if (!strcmp(field_name, (*op->qf->input_fields[i]).field_name)) { 768d1d35e2fSjeremylt qf_field = op->qf->input_fields[i]; 769d1d35e2fSjeremylt op_field = &op->input_fields[i]; 770d7b241e6Sjeremylt goto found; 771d7b241e6Sjeremylt } 772d7b241e6Sjeremylt } 7732b104005SJeremy L Thompson is_input = false; 774d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_output_fields; i++) { 775d1d35e2fSjeremylt if (!strcmp(field_name, (*op->qf->output_fields[i]).field_name)) { 776d1d35e2fSjeremylt qf_field = op->qf->output_fields[i]; 777d1d35e2fSjeremylt op_field = &op->output_fields[i]; 778d7b241e6Sjeremylt goto found; 779d7b241e6Sjeremylt } 780d7b241e6Sjeremylt } 781c042f62fSJeremy L Thompson // LCOV_EXCL_START 782e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPLETE, 783e15f9bd0SJeremy L Thompson "QFunction has no knowledge of field '%s'", 784d1d35e2fSjeremylt field_name); 785c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 786d7b241e6Sjeremylt found: 787d1d35e2fSjeremylt ierr = CeedOperatorCheckField(op->ceed, qf_field, r, b); CeedChk(ierr); 788d1d35e2fSjeremylt ierr = CeedCalloc(1, op_field); CeedChk(ierr); 789e15f9bd0SJeremy L Thompson 7902b104005SJeremy L Thompson if (v == CEED_VECTOR_ACTIVE) { 7912b104005SJeremy L Thompson CeedSize l_size; 7922b104005SJeremy L Thompson ierr = CeedElemRestrictionGetLVectorSize(r, &l_size); CeedChk(ierr); 7932b104005SJeremy L Thompson if (is_input) { 7942b104005SJeremy L Thompson if (op->input_size == -1) op->input_size = l_size; 7952b104005SJeremy L Thompson if (l_size != op->input_size) 7962b104005SJeremy L Thompson // LCOV_EXCL_START 7972b104005SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 7982b104005SJeremy L Thompson "LVector size %td does not match previous size %td", 7992b104005SJeremy L Thompson l_size, op->input_size); 8002b104005SJeremy L Thompson // LCOV_EXCL_STOP 8012b104005SJeremy L Thompson } else { 8022b104005SJeremy L Thompson if (op->output_size == -1) op->output_size = l_size; 8032b104005SJeremy L Thompson if (l_size != op->output_size) 8042b104005SJeremy L Thompson // LCOV_EXCL_START 8052b104005SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 8062b104005SJeremy L Thompson "LVector size %td does not match previous size %td", 8072b104005SJeremy L Thompson l_size, op->output_size); 8082b104005SJeremy L Thompson // LCOV_EXCL_STOP 8092b104005SJeremy L Thompson } 8102b104005SJeremy L Thompson } 8112b104005SJeremy L Thompson 812d1d35e2fSjeremylt (*op_field)->vec = v; 813e15f9bd0SJeremy L Thompson if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE) { 8149560d06aSjeremylt ierr = CeedVectorReference(v); CeedChk(ierr); 815e15f9bd0SJeremy L Thompson } 816e15f9bd0SJeremy L Thompson 817d1d35e2fSjeremylt (*op_field)->elem_restr = r; 8189560d06aSjeremylt ierr = CeedElemRestrictionReference(r); CeedChk(ierr); 819e15f9bd0SJeremy L Thompson if (r != CEED_ELEMRESTRICTION_NONE) { 820d1d35e2fSjeremylt op->num_elem = num_elem; 821d1d35e2fSjeremylt op->has_restriction = true; // Restriction set, but num_elem may be 0 822e15f9bd0SJeremy L Thompson } 823d99fa3c5SJeremy L Thompson 824d1d35e2fSjeremylt (*op_field)->basis = b; 825e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 826cd4dfc48Sjeremylt if (!op->num_qpts) { 827cd4dfc48Sjeremylt ierr = CeedOperatorSetNumQuadraturePoints(op, num_qpts); CeedChk(ierr); 828cd4dfc48Sjeremylt } 8299560d06aSjeremylt ierr = CeedBasisReference(b); CeedChk(ierr); 830e15f9bd0SJeremy L Thompson } 831e15f9bd0SJeremy L Thompson 832d1d35e2fSjeremylt op->num_fields += 1; 833f7e22acaSJeremy L Thompson ierr = CeedStringAllocCopy(field_name, (char **)&(*op_field)->field_name); 834f7e22acaSJeremy L Thompson CeedChk(ierr); 835e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 836d7b241e6Sjeremylt } 837d7b241e6Sjeremylt 838d7b241e6Sjeremylt /** 83943bbe138SJeremy L Thompson @brief Get the CeedOperatorFields of a CeedOperator 84043bbe138SJeremy L Thompson 841f04ea552SJeremy L Thompson Note: Calling this function asserts that setup is complete 842f04ea552SJeremy L Thompson and sets the CeedOperator as immutable. 843f04ea552SJeremy L Thompson 84443bbe138SJeremy L Thompson @param op CeedOperator 845f74ec584SJeremy L Thompson @param[out] num_input_fields Variable to store number of input fields 84643bbe138SJeremy L Thompson @param[out] input_fields Variable to store input_fields 847f74ec584SJeremy L Thompson @param[out] num_output_fields Variable to store number of output fields 84843bbe138SJeremy L Thompson @param[out] output_fields Variable to store output_fields 84943bbe138SJeremy L Thompson 85043bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 85143bbe138SJeremy L Thompson 852e9b533fbSJeremy L Thompson @ref Advanced 85343bbe138SJeremy L Thompson **/ 85443bbe138SJeremy L Thompson int CeedOperatorGetFields(CeedOperator op, CeedInt *num_input_fields, 85543bbe138SJeremy L Thompson CeedOperatorField **input_fields, 85643bbe138SJeremy L Thompson CeedInt *num_output_fields, 85743bbe138SJeremy L Thompson CeedOperatorField **output_fields) { 858f04ea552SJeremy L Thompson int ierr; 859f04ea552SJeremy L Thompson 860f04ea552SJeremy L Thompson if (op->is_composite) 86143bbe138SJeremy L Thompson // LCOV_EXCL_START 86243bbe138SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 86343bbe138SJeremy L Thompson "Not defined for composite operator"); 86443bbe138SJeremy L Thompson // LCOV_EXCL_STOP 865f04ea552SJeremy L Thompson ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 86643bbe138SJeremy L Thompson 86743bbe138SJeremy L Thompson if (num_input_fields) *num_input_fields = op->qf->num_input_fields; 86843bbe138SJeremy L Thompson if (input_fields) *input_fields = op->input_fields; 86943bbe138SJeremy L Thompson if (num_output_fields) *num_output_fields = op->qf->num_output_fields; 87043bbe138SJeremy L Thompson if (output_fields) *output_fields = op->output_fields; 87143bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 87243bbe138SJeremy L Thompson } 87343bbe138SJeremy L Thompson 87443bbe138SJeremy L Thompson /** 87528567f8fSJeremy L Thompson @brief Get the name of a CeedOperatorField 87628567f8fSJeremy L Thompson 87728567f8fSJeremy L Thompson @param op_field CeedOperatorField 87828567f8fSJeremy L Thompson @param[out] field_name Variable to store the field name 87928567f8fSJeremy L Thompson 88028567f8fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 88128567f8fSJeremy L Thompson 882e9b533fbSJeremy L Thompson @ref Advanced 88328567f8fSJeremy L Thompson **/ 88428567f8fSJeremy L Thompson int CeedOperatorFieldGetName(CeedOperatorField op_field, char **field_name) { 88528567f8fSJeremy L Thompson *field_name = (char *)op_field->field_name; 88628567f8fSJeremy L Thompson return CEED_ERROR_SUCCESS; 88728567f8fSJeremy L Thompson } 88828567f8fSJeremy L Thompson 88928567f8fSJeremy L Thompson /** 89043bbe138SJeremy L Thompson @brief Get the CeedElemRestriction of a CeedOperatorField 89143bbe138SJeremy L Thompson 89243bbe138SJeremy L Thompson @param op_field CeedOperatorField 89343bbe138SJeremy L Thompson @param[out] rstr Variable to store CeedElemRestriction 89443bbe138SJeremy L Thompson 89543bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 89643bbe138SJeremy L Thompson 897e9b533fbSJeremy L Thompson @ref Advanced 89843bbe138SJeremy L Thompson **/ 89943bbe138SJeremy L Thompson int CeedOperatorFieldGetElemRestriction(CeedOperatorField op_field, 90043bbe138SJeremy L Thompson CeedElemRestriction *rstr) { 90143bbe138SJeremy L Thompson *rstr = op_field->elem_restr; 90243bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 90343bbe138SJeremy L Thompson } 90443bbe138SJeremy L Thompson 90543bbe138SJeremy L Thompson /** 90643bbe138SJeremy L Thompson @brief Get the CeedBasis of a CeedOperatorField 90743bbe138SJeremy L Thompson 90843bbe138SJeremy L Thompson @param op_field CeedOperatorField 90943bbe138SJeremy L Thompson @param[out] basis Variable to store CeedBasis 91043bbe138SJeremy L Thompson 91143bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 91243bbe138SJeremy L Thompson 913e9b533fbSJeremy L Thompson @ref Advanced 91443bbe138SJeremy L Thompson **/ 91543bbe138SJeremy L Thompson int CeedOperatorFieldGetBasis(CeedOperatorField op_field, CeedBasis *basis) { 91643bbe138SJeremy L Thompson *basis = op_field->basis; 91743bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 91843bbe138SJeremy L Thompson } 91943bbe138SJeremy L Thompson 92043bbe138SJeremy L Thompson /** 92143bbe138SJeremy L Thompson @brief Get the CeedVector of a CeedOperatorField 92243bbe138SJeremy L Thompson 92343bbe138SJeremy L Thompson @param op_field CeedOperatorField 92443bbe138SJeremy L Thompson @param[out] vec Variable to store CeedVector 92543bbe138SJeremy L Thompson 92643bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 92743bbe138SJeremy L Thompson 928e9b533fbSJeremy L Thompson @ref Advanced 92943bbe138SJeremy L Thompson **/ 93043bbe138SJeremy L Thompson int CeedOperatorFieldGetVector(CeedOperatorField op_field, CeedVector *vec) { 93143bbe138SJeremy L Thompson *vec = op_field->vec; 93243bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 93343bbe138SJeremy L Thompson } 93443bbe138SJeremy L Thompson 93543bbe138SJeremy L Thompson /** 93652d6035fSJeremy L Thompson @brief Add a sub-operator to a composite CeedOperator 937288c0443SJeremy L Thompson 938d1d35e2fSjeremylt @param[out] composite_op Composite CeedOperator 939d1d35e2fSjeremylt @param sub_op Sub-operator CeedOperator 94052d6035fSJeremy L Thompson 94152d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 94252d6035fSJeremy L Thompson 9437a982d89SJeremy L. Thompson @ref User 94452d6035fSJeremy L Thompson */ 945d1d35e2fSjeremylt int CeedCompositeOperatorAddSub(CeedOperator composite_op, 946d1d35e2fSjeremylt CeedOperator sub_op) { 94734359f16Sjeremylt int ierr; 94834359f16Sjeremylt 949f04ea552SJeremy L Thompson if (!composite_op->is_composite) 950c042f62fSJeremy L Thompson // LCOV_EXCL_START 951d1d35e2fSjeremylt return CeedError(composite_op->ceed, CEED_ERROR_MINOR, 952e2f04181SAndrew T. Barker "CeedOperator is not a composite operator"); 953c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 95452d6035fSJeremy L Thompson 955d1d35e2fSjeremylt if (composite_op->num_suboperators == CEED_COMPOSITE_MAX) 956c042f62fSJeremy L Thompson // LCOV_EXCL_START 957d1d35e2fSjeremylt return CeedError(composite_op->ceed, CEED_ERROR_UNSUPPORTED, 9582b104005SJeremy L Thompson "Cannot add additional sub-operators"); 959c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 960f04ea552SJeremy L Thompson if (composite_op->is_immutable) 961f04ea552SJeremy L Thompson // LCOV_EXCL_START 962f04ea552SJeremy L Thompson return CeedError(composite_op->ceed, CEED_ERROR_MAJOR, 963f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 964f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 96552d6035fSJeremy L Thompson 9662b104005SJeremy L Thompson { 9672b104005SJeremy L Thompson CeedSize input_size, output_size; 9682b104005SJeremy L Thompson ierr = CeedOperatorGetActiveVectorLengths(sub_op, &input_size, &output_size); 9692b104005SJeremy L Thompson CeedChk(ierr); 9702b104005SJeremy L Thompson if (composite_op->input_size == -1) composite_op->input_size = input_size; 9712b104005SJeremy L Thompson if (composite_op->output_size == -1) composite_op->output_size = output_size; 9722b104005SJeremy L Thompson // Note, a size of -1 means no active vector restriction set, so no incompatibility 9732b104005SJeremy L Thompson if ((input_size != -1 && input_size != composite_op->input_size) || 9742b104005SJeremy L Thompson (output_size != -1 && output_size != composite_op->output_size)) 9752b104005SJeremy L Thompson // LCOV_EXCL_START 9762b104005SJeremy L Thompson return CeedError(composite_op->ceed, CEED_ERROR_MAJOR, 9772b104005SJeremy L Thompson "Sub-operators must have compatible dimensions; " 9782b104005SJeremy L Thompson "composite operator of shape (%td, %td) not compatible with " 9792b104005SJeremy L Thompson "sub-operator of shape (%td, %td)", 9802b104005SJeremy L Thompson composite_op->input_size, composite_op->output_size, input_size, output_size); 9812b104005SJeremy L Thompson // LCOV_EXCL_STOP 9822b104005SJeremy L Thompson } 9832b104005SJeremy L Thompson 984d1d35e2fSjeremylt composite_op->sub_operators[composite_op->num_suboperators] = sub_op; 9859560d06aSjeremylt ierr = CeedOperatorReference(sub_op); CeedChk(ierr); 986d1d35e2fSjeremylt composite_op->num_suboperators++; 987e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 98852d6035fSJeremy L Thompson } 98952d6035fSJeremy L Thompson 99052d6035fSJeremy L Thompson /** 9914db537f9SJeremy L Thompson @brief Check if a CeedOperator is ready to be used. 9924db537f9SJeremy L Thompson 9934db537f9SJeremy L Thompson @param[in] op CeedOperator to check 9944db537f9SJeremy L Thompson 9954db537f9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 9964db537f9SJeremy L Thompson 9974db537f9SJeremy L Thompson @ref User 9984db537f9SJeremy L Thompson **/ 9994db537f9SJeremy L Thompson int CeedOperatorCheckReady(CeedOperator op) { 10004db537f9SJeremy L Thompson int ierr; 10014db537f9SJeremy L Thompson Ceed ceed; 10024db537f9SJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 10034db537f9SJeremy L Thompson 10044db537f9SJeremy L Thompson if (op->is_interface_setup) 10054db537f9SJeremy L Thompson return CEED_ERROR_SUCCESS; 10064db537f9SJeremy L Thompson 10074db537f9SJeremy L Thompson CeedQFunction qf = op->qf; 10084db537f9SJeremy L Thompson if (op->is_composite) { 10094db537f9SJeremy L Thompson if (!op->num_suboperators) 10104db537f9SJeremy L Thompson // LCOV_EXCL_START 10114db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "No sub_operators set"); 10124db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10134db537f9SJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 10144db537f9SJeremy L Thompson ierr = CeedOperatorCheckReady(op->sub_operators[i]); CeedChk(ierr); 10154db537f9SJeremy L Thompson } 10162b104005SJeremy L Thompson // Sub-operators could be modified after adding to composite operator 10172b104005SJeremy L Thompson // Need to verify no lvec incompatibility from any changes 10182b104005SJeremy L Thompson CeedSize input_size, output_size; 10192b104005SJeremy L Thompson ierr = CeedOperatorGetActiveVectorLengths(op, &input_size, &output_size); 10202b104005SJeremy L Thompson CeedChk(ierr); 10214db537f9SJeremy L Thompson } else { 10224db537f9SJeremy L Thompson if (op->num_fields == 0) 10234db537f9SJeremy L Thompson // LCOV_EXCL_START 10244db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "No operator fields set"); 10254db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10264db537f9SJeremy L Thompson if (op->num_fields < qf->num_input_fields + qf->num_output_fields) 10274db537f9SJeremy L Thompson // LCOV_EXCL_START 10284db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "Not all operator fields set"); 10294db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10304db537f9SJeremy L Thompson if (!op->has_restriction) 10314db537f9SJeremy L Thompson // LCOV_EXCL_START 10324db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, 10334db537f9SJeremy L Thompson "At least one restriction required"); 10344db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10354db537f9SJeremy L Thompson if (op->num_qpts == 0) 10364db537f9SJeremy L Thompson // LCOV_EXCL_START 10374db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, 10384db537f9SJeremy L Thompson "At least one non-collocated basis is required " 10394db537f9SJeremy L Thompson "or the number of quadrature points must be set"); 10404db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10414db537f9SJeremy L Thompson } 10424db537f9SJeremy L Thompson 10434db537f9SJeremy L Thompson // Flag as immutable and ready 10444db537f9SJeremy L Thompson op->is_interface_setup = true; 10454db537f9SJeremy L Thompson if (op->qf && op->qf != CEED_QFUNCTION_NONE) 10464db537f9SJeremy L Thompson // LCOV_EXCL_START 10474db537f9SJeremy L Thompson op->qf->is_immutable = true; 10484db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10494db537f9SJeremy L Thompson if (op->dqf && op->dqf != CEED_QFUNCTION_NONE) 10504db537f9SJeremy L Thompson // LCOV_EXCL_START 10514db537f9SJeremy L Thompson op->dqf->is_immutable = true; 10524db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10534db537f9SJeremy L Thompson if (op->dqfT && op->dqfT != CEED_QFUNCTION_NONE) 10544db537f9SJeremy L Thompson // LCOV_EXCL_START 10554db537f9SJeremy L Thompson op->dqfT->is_immutable = true; 10564db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10574db537f9SJeremy L Thompson return CEED_ERROR_SUCCESS; 10584db537f9SJeremy L Thompson } 10594db537f9SJeremy L Thompson 10604db537f9SJeremy L Thompson /** 1061c9366a6bSJeremy L Thompson @brief Get vector lengths for the active input and/or output vectors of a CeedOperator. 1062c9366a6bSJeremy L Thompson Note: Lengths of -1 indicate that the CeedOperator does not have an 1063c9366a6bSJeremy L Thompson active input and/or output. 1064c9366a6bSJeremy L Thompson 1065c9366a6bSJeremy L Thompson @param[in] op CeedOperator 1066c9366a6bSJeremy L Thompson @param[out] input_size Variable to store active input vector length, or NULL 1067c9366a6bSJeremy L Thompson @param[out] output_size Variable to store active output vector length, or NULL 1068c9366a6bSJeremy L Thompson 1069c9366a6bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1070c9366a6bSJeremy L Thompson 1071c9366a6bSJeremy L Thompson @ref User 1072c9366a6bSJeremy L Thompson **/ 1073c9366a6bSJeremy L Thompson int CeedOperatorGetActiveVectorLengths(CeedOperator op, CeedSize *input_size, 1074c9366a6bSJeremy L Thompson CeedSize *output_size) { 1075c9366a6bSJeremy L Thompson int ierr; 1076c9366a6bSJeremy L Thompson bool is_composite; 1077c9366a6bSJeremy L Thompson 10782b104005SJeremy L Thompson if (input_size) *input_size = op->input_size; 10792b104005SJeremy L Thompson if (output_size) *output_size = op->output_size; 1080c9366a6bSJeremy L Thompson 1081c9366a6bSJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 10822b104005SJeremy L Thompson if (is_composite && (op->input_size == -1 || op->output_size == -1)) { 1083c9366a6bSJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 1084c9366a6bSJeremy L Thompson CeedSize sub_input_size, sub_output_size; 1085c9366a6bSJeremy L Thompson ierr = CeedOperatorGetActiveVectorLengths(op->sub_operators[i], 10862b104005SJeremy L Thompson &sub_input_size, &sub_output_size); CeedChk(ierr); 10872b104005SJeremy L Thompson if (op->input_size == -1) op->input_size = sub_input_size; 10882b104005SJeremy L Thompson if (op->output_size == -1) op->output_size = sub_output_size; 10892b104005SJeremy L Thompson // Note, a size of -1 means no active vector restriction set, so no incompatibility 10902b104005SJeremy L Thompson if ((sub_input_size != -1 && sub_input_size != op->input_size) || 10912b104005SJeremy L Thompson (sub_output_size != -1 && sub_output_size != op->output_size)) 10922b104005SJeremy L Thompson // LCOV_EXCL_START 10932b104005SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 10942b104005SJeremy L Thompson "Sub-operators must have compatible dimensions; " 10952b104005SJeremy L Thompson "composite operator of shape (%td, %td) not compatible with " 10962b104005SJeremy L Thompson "sub-operator of shape (%td, %td)", 10972b104005SJeremy L Thompson op->input_size, op->output_size, input_size, output_size); 10982b104005SJeremy L Thompson // LCOV_EXCL_STOP 1099c9366a6bSJeremy L Thompson } 1100c9366a6bSJeremy L Thompson } 1101c9366a6bSJeremy L Thompson 1102c9366a6bSJeremy L Thompson return CEED_ERROR_SUCCESS; 1103c9366a6bSJeremy L Thompson } 1104c9366a6bSJeremy L Thompson 1105c9366a6bSJeremy L Thompson /** 1106beecbf24SJeremy L Thompson @brief Set reuse of CeedQFunction data in CeedOperatorLinearAssemble* functions. 1107beecbf24SJeremy L Thompson When `reuse_assembly_data = false` (default), the CeedQFunction associated 1108beecbf24SJeremy L Thompson with this CeedOperator is re-assembled every time a `CeedOperatorLinearAssemble*` 1109beecbf24SJeremy L Thompson function is called. 1110beecbf24SJeremy L Thompson When `reuse_assembly_data = true`, the CeedQFunction associated with 1111beecbf24SJeremy L Thompson this CeedOperator is reused between calls to 1112beecbf24SJeremy L Thompson `CeedOperatorSetQFunctionAssemblyDataUpdated`. 11138b919e6bSJeremy L Thompson 1114beecbf24SJeremy L Thompson @param[in] op CeedOperator 1115beecbf24SJeremy L Thompson @param[in] reuse_assembly_data Boolean flag setting assembly data reuse 11168b919e6bSJeremy L Thompson 11178b919e6bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 11188b919e6bSJeremy L Thompson 11198b919e6bSJeremy L Thompson @ref Advanced 11208b919e6bSJeremy L Thompson **/ 1121beecbf24SJeremy L Thompson int CeedOperatorSetQFunctionAssemblyReuse(CeedOperator op, 1122beecbf24SJeremy L Thompson bool reuse_assembly_data) { 11238b919e6bSJeremy L Thompson int ierr; 11248b919e6bSJeremy L Thompson bool is_composite; 11258b919e6bSJeremy L Thompson 11268b919e6bSJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 11278b919e6bSJeremy L Thompson if (is_composite) { 11288b919e6bSJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 1129beecbf24SJeremy L Thompson ierr = CeedOperatorSetQFunctionAssemblyReuse(op->sub_operators[i], 1130beecbf24SJeremy L Thompson reuse_assembly_data); CeedChk(ierr); 11318b919e6bSJeremy L Thompson } 11328b919e6bSJeremy L Thompson } else { 1133beecbf24SJeremy L Thompson ierr = CeedQFunctionAssemblyDataSetReuse(op->qf_assembled, reuse_assembly_data); 1134beecbf24SJeremy L Thompson CeedChk(ierr); 1135beecbf24SJeremy L Thompson } 1136beecbf24SJeremy L Thompson 1137beecbf24SJeremy L Thompson return CEED_ERROR_SUCCESS; 1138beecbf24SJeremy L Thompson } 1139beecbf24SJeremy L Thompson 1140beecbf24SJeremy L Thompson /** 1141beecbf24SJeremy L Thompson @brief Mark CeedQFunction data as updated and the CeedQFunction as requiring re-assembly. 1142beecbf24SJeremy L Thompson 1143beecbf24SJeremy L Thompson @param[in] op CeedOperator 11446e15d496SJeremy L Thompson @param[in] needs_data_update Boolean flag setting assembly data reuse 1145beecbf24SJeremy L Thompson 1146beecbf24SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1147beecbf24SJeremy L Thompson 1148beecbf24SJeremy L Thompson @ref Advanced 1149beecbf24SJeremy L Thompson **/ 1150beecbf24SJeremy L Thompson int CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(CeedOperator op, 1151beecbf24SJeremy L Thompson bool needs_data_update) { 1152beecbf24SJeremy L Thompson int ierr; 1153beecbf24SJeremy L Thompson bool is_composite; 1154beecbf24SJeremy L Thompson 1155beecbf24SJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 1156beecbf24SJeremy L Thompson if (is_composite) { 1157beecbf24SJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 1158beecbf24SJeremy L Thompson ierr = CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(op->sub_operators[i], 1159beecbf24SJeremy L Thompson needs_data_update); CeedChk(ierr); 1160beecbf24SJeremy L Thompson } 1161beecbf24SJeremy L Thompson } else { 1162beecbf24SJeremy L Thompson ierr = CeedQFunctionAssemblyDataSetUpdateNeeded(op->qf_assembled, 1163beecbf24SJeremy L Thompson needs_data_update); 11648b919e6bSJeremy L Thompson CeedChk(ierr); 11658b919e6bSJeremy L Thompson } 11668b919e6bSJeremy L Thompson 11678b919e6bSJeremy L Thompson return CEED_ERROR_SUCCESS; 11688b919e6bSJeremy L Thompson } 11698b919e6bSJeremy L Thompson 11708b919e6bSJeremy L Thompson /** 1171cd4dfc48Sjeremylt @brief Set the number of quadrature points associated with a CeedOperator. 1172cd4dfc48Sjeremylt This should be used when creating a CeedOperator where every 1173cd4dfc48Sjeremylt field has a collocated basis. This function cannot be used for 1174cd4dfc48Sjeremylt composite CeedOperators. 1175cd4dfc48Sjeremylt 1176cd4dfc48Sjeremylt @param op CeedOperator 1177cd4dfc48Sjeremylt @param num_qpts Number of quadrature points to set 1178cd4dfc48Sjeremylt 1179cd4dfc48Sjeremylt @return An error code: 0 - success, otherwise - failure 1180cd4dfc48Sjeremylt 1181e9b533fbSJeremy L Thompson @ref Advanced 1182cd4dfc48Sjeremylt **/ 1183cd4dfc48Sjeremylt int CeedOperatorSetNumQuadraturePoints(CeedOperator op, CeedInt num_qpts) { 1184f04ea552SJeremy L Thompson if (op->is_composite) 1185cd4dfc48Sjeremylt // LCOV_EXCL_START 1186cd4dfc48Sjeremylt return CeedError(op->ceed, CEED_ERROR_MINOR, 1187cd4dfc48Sjeremylt "Not defined for composite operator"); 1188cd4dfc48Sjeremylt // LCOV_EXCL_STOP 1189cd4dfc48Sjeremylt if (op->num_qpts) 1190cd4dfc48Sjeremylt // LCOV_EXCL_START 1191cd4dfc48Sjeremylt return CeedError(op->ceed, CEED_ERROR_MINOR, 1192cd4dfc48Sjeremylt "Number of quadrature points already defined"); 1193cd4dfc48Sjeremylt // LCOV_EXCL_STOP 1194f04ea552SJeremy L Thompson if (op->is_immutable) 1195f04ea552SJeremy L Thompson // LCOV_EXCL_START 1196f04ea552SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 1197f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 1198f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 1199cd4dfc48Sjeremylt 1200cd4dfc48Sjeremylt op->num_qpts = num_qpts; 1201cd4dfc48Sjeremylt return CEED_ERROR_SUCCESS; 1202cd4dfc48Sjeremylt } 1203cd4dfc48Sjeremylt 1204cd4dfc48Sjeremylt /** 1205ea6b5821SJeremy L Thompson @brief Set name of CeedOperator for CeedOperatorView output 1206ea6b5821SJeremy L Thompson 1207ea6b5821SJeremy L Thompson @param op CeedOperator 1208ea6b5821SJeremy L Thompson @param name Name to set, or NULL to remove previously set name 1209ea6b5821SJeremy L Thompson 1210ea6b5821SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1211ea6b5821SJeremy L Thompson 1212ea6b5821SJeremy L Thompson @ref User 1213ea6b5821SJeremy L Thompson **/ 1214ea6b5821SJeremy L Thompson int CeedOperatorSetName(CeedOperator op, const char *name) { 1215ea6b5821SJeremy L Thompson int ierr; 1216ea6b5821SJeremy L Thompson char *name_copy; 1217ea6b5821SJeremy L Thompson size_t name_len = name ? strlen(name) : 0; 1218ea6b5821SJeremy L Thompson 1219ea6b5821SJeremy L Thompson ierr = CeedFree(&op->name); CeedChk(ierr); 1220ea6b5821SJeremy L Thompson if (name_len > 0) { 1221ea6b5821SJeremy L Thompson ierr = CeedCalloc(name_len + 1, &name_copy); CeedChk(ierr); 1222ea6b5821SJeremy L Thompson memcpy(name_copy, name, name_len); 1223ea6b5821SJeremy L Thompson op->name = name_copy; 1224ea6b5821SJeremy L Thompson } 1225ea6b5821SJeremy L Thompson 1226ea6b5821SJeremy L Thompson return CEED_ERROR_SUCCESS; 1227ea6b5821SJeremy L Thompson } 1228ea6b5821SJeremy L Thompson 1229ea6b5821SJeremy L Thompson /** 12307a982d89SJeremy L. Thompson @brief View a CeedOperator 12317a982d89SJeremy L. Thompson 12327a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 12337a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 12347a982d89SJeremy L. Thompson 12357a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 12367a982d89SJeremy L. Thompson 12377a982d89SJeremy L. Thompson @ref User 12387a982d89SJeremy L. Thompson **/ 12397a982d89SJeremy L. Thompson int CeedOperatorView(CeedOperator op, FILE *stream) { 12407a982d89SJeremy L. Thompson int ierr; 1241ea6b5821SJeremy L Thompson bool has_name = op->name; 12427a982d89SJeremy L. Thompson 1243f04ea552SJeremy L Thompson if (op->is_composite) { 1244ea6b5821SJeremy L Thompson fprintf(stream, "Composite CeedOperator%s%s\n", 1245ea6b5821SJeremy L Thompson has_name ? " - " : "", has_name ? op->name : ""); 12467a982d89SJeremy L. Thompson 1247d1d35e2fSjeremylt for (CeedInt i=0; i<op->num_suboperators; i++) { 1248ea6b5821SJeremy L Thompson has_name = op->sub_operators[i]->name; 1249990fdeb6SJeremy L Thompson fprintf(stream, " SubOperator %" CeedInt_FMT "%s%s:\n", i, 1250ea6b5821SJeremy L Thompson has_name ? " - " : "", 1251ea6b5821SJeremy L Thompson has_name ? op->sub_operators[i]->name : ""); 1252d1d35e2fSjeremylt ierr = CeedOperatorSingleView(op->sub_operators[i], 1, stream); 12537a982d89SJeremy L. Thompson CeedChk(ierr); 12547a982d89SJeremy L. Thompson } 12557a982d89SJeremy L. Thompson } else { 1256ea6b5821SJeremy L Thompson fprintf(stream, "CeedOperator%s%s\n", 1257ea6b5821SJeremy L Thompson has_name ? " - " : "", has_name ? op->name : ""); 12587a982d89SJeremy L. Thompson ierr = CeedOperatorSingleView(op, 0, stream); CeedChk(ierr); 12597a982d89SJeremy L. Thompson } 1260e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 12617a982d89SJeremy L. Thompson } 12623bd813ffSjeremylt 12633bd813ffSjeremylt /** 1264b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedOperator 1265b7c9bbdaSJeremy L Thompson 1266b7c9bbdaSJeremy L Thompson @param op CeedOperator 1267b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 1268b7c9bbdaSJeremy L Thompson 1269b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1270b7c9bbdaSJeremy L Thompson 1271b7c9bbdaSJeremy L Thompson @ref Advanced 1272b7c9bbdaSJeremy L Thompson **/ 1273b7c9bbdaSJeremy L Thompson int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 1274b7c9bbdaSJeremy L Thompson *ceed = op->ceed; 1275b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1276b7c9bbdaSJeremy L Thompson } 1277b7c9bbdaSJeremy L Thompson 1278b7c9bbdaSJeremy L Thompson /** 1279b7c9bbdaSJeremy L Thompson @brief Get the number of elements associated with a CeedOperator 1280b7c9bbdaSJeremy L Thompson 1281b7c9bbdaSJeremy L Thompson @param op CeedOperator 1282b7c9bbdaSJeremy L Thompson @param[out] num_elem Variable to store number of elements 1283b7c9bbdaSJeremy L Thompson 1284b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1285b7c9bbdaSJeremy L Thompson 1286b7c9bbdaSJeremy L Thompson @ref Advanced 1287b7c9bbdaSJeremy L Thompson **/ 1288b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumElements(CeedOperator op, CeedInt *num_elem) { 1289b7c9bbdaSJeremy L Thompson if (op->is_composite) 1290b7c9bbdaSJeremy L Thompson // LCOV_EXCL_START 1291b7c9bbdaSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 1292b7c9bbdaSJeremy L Thompson "Not defined for composite operator"); 1293b7c9bbdaSJeremy L Thompson // LCOV_EXCL_STOP 1294b7c9bbdaSJeremy L Thompson 1295b7c9bbdaSJeremy L Thompson *num_elem = op->num_elem; 1296b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1297b7c9bbdaSJeremy L Thompson } 1298b7c9bbdaSJeremy L Thompson 1299b7c9bbdaSJeremy L Thompson /** 1300b7c9bbdaSJeremy L Thompson @brief Get the number of quadrature points associated with a CeedOperator 1301b7c9bbdaSJeremy L Thompson 1302b7c9bbdaSJeremy L Thompson @param op CeedOperator 1303b7c9bbdaSJeremy L Thompson @param[out] num_qpts Variable to store vector number of quadrature points 1304b7c9bbdaSJeremy L Thompson 1305b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1306b7c9bbdaSJeremy L Thompson 1307b7c9bbdaSJeremy L Thompson @ref Advanced 1308b7c9bbdaSJeremy L Thompson **/ 1309b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *num_qpts) { 1310b7c9bbdaSJeremy L Thompson if (op->is_composite) 1311b7c9bbdaSJeremy L Thompson // LCOV_EXCL_START 1312b7c9bbdaSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 1313b7c9bbdaSJeremy L Thompson "Not defined for composite operator"); 1314b7c9bbdaSJeremy L Thompson // LCOV_EXCL_STOP 1315b7c9bbdaSJeremy L Thompson 1316b7c9bbdaSJeremy L Thompson *num_qpts = op->num_qpts; 1317b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1318b7c9bbdaSJeremy L Thompson } 1319b7c9bbdaSJeremy L Thompson 1320b7c9bbdaSJeremy L Thompson /** 13216e15d496SJeremy L Thompson @brief Estimate number of FLOPs required to apply CeedOperator on the active vector 13226e15d496SJeremy L Thompson 13236e15d496SJeremy L Thompson @param op Operator to estimate FLOPs for 13246e15d496SJeremy L Thompson @param flops Address of variable to hold FLOPs estimate 13256e15d496SJeremy L Thompson 13266e15d496SJeremy L Thompson @ref Backend 13276e15d496SJeremy L Thompson **/ 13289d36ca50SJeremy L Thompson int CeedOperatorGetFlopsEstimate(CeedOperator op, CeedSize *flops) { 13296e15d496SJeremy L Thompson int ierr; 13306e15d496SJeremy L Thompson bool is_composite; 13316e15d496SJeremy L Thompson ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 13326e15d496SJeremy L Thompson 13336e15d496SJeremy L Thompson *flops = 0; 13346e15d496SJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 13356e15d496SJeremy L Thompson if (is_composite) { 13366e15d496SJeremy L Thompson CeedInt num_suboperators; 13376e15d496SJeremy L Thompson ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 13386e15d496SJeremy L Thompson CeedOperator *sub_operators; 13396e15d496SJeremy L Thompson ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 13406e15d496SJeremy L Thompson 13416e15d496SJeremy L Thompson // FLOPs for each suboperator 13426e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 13439d36ca50SJeremy L Thompson CeedSize suboperator_flops; 13446e15d496SJeremy L Thompson ierr = CeedOperatorGetFlopsEstimate(sub_operators[i], &suboperator_flops); 13456e15d496SJeremy L Thompson CeedChk(ierr); 13466e15d496SJeremy L Thompson *flops += suboperator_flops; 13476e15d496SJeremy L Thompson } 13486e15d496SJeremy L Thompson } else { 13496e15d496SJeremy L Thompson CeedInt num_input_fields, num_output_fields; 13506e15d496SJeremy L Thompson CeedOperatorField *input_fields, *output_fields; 13516e15d496SJeremy L Thompson 13526e15d496SJeremy L Thompson ierr = CeedOperatorGetFields(op, &num_input_fields, &input_fields, 13536e15d496SJeremy L Thompson &num_output_fields, &output_fields); CeedChk(ierr); 13546e15d496SJeremy L Thompson 13556e15d496SJeremy L Thompson CeedInt num_elem = 0; 13566e15d496SJeremy L Thompson ierr = CeedOperatorGetNumElements(op, &num_elem); CeedChk(ierr); 13576e15d496SJeremy L Thompson // Input FLOPs 13586e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_input_fields; i++) { 13596e15d496SJeremy L Thompson if (input_fields[i]->vec == CEED_VECTOR_ACTIVE) { 13609d36ca50SJeremy L Thompson CeedSize restr_flops, basis_flops; 13616e15d496SJeremy L Thompson 13626e15d496SJeremy L Thompson ierr = CeedElemRestrictionGetFlopsEstimate(input_fields[i]->elem_restr, 13636e15d496SJeremy L Thompson CEED_NOTRANSPOSE, &restr_flops); CeedChk(ierr); 13646e15d496SJeremy L Thompson *flops += restr_flops; 13656e15d496SJeremy L Thompson ierr = CeedBasisGetFlopsEstimate(input_fields[i]->basis, CEED_NOTRANSPOSE, 13666e15d496SJeremy L Thompson op->qf->input_fields[i]->eval_mode, &basis_flops); CeedChk(ierr); 13676e15d496SJeremy L Thompson *flops += basis_flops * num_elem; 13686e15d496SJeremy L Thompson } 13696e15d496SJeremy L Thompson } 13706e15d496SJeremy L Thompson // QF FLOPs 13719d36ca50SJeremy L Thompson CeedInt num_qpts; 13729d36ca50SJeremy L Thompson CeedSize qf_flops; 13736e15d496SJeremy L Thompson ierr = CeedOperatorGetNumQuadraturePoints(op, &num_qpts); CeedChk(ierr); 13746e15d496SJeremy L Thompson ierr = CeedQFunctionGetFlopsEstimate(op->qf, &qf_flops); CeedChk(ierr); 13756e15d496SJeremy L Thompson *flops += num_elem * num_qpts * qf_flops; 13766e15d496SJeremy L Thompson // Output FLOPs 13776e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_output_fields; i++) { 13786e15d496SJeremy L Thompson if (output_fields[i]->vec == CEED_VECTOR_ACTIVE) { 13799d36ca50SJeremy L Thompson CeedSize restr_flops, basis_flops; 13806e15d496SJeremy L Thompson 13816e15d496SJeremy L Thompson ierr = CeedElemRestrictionGetFlopsEstimate(output_fields[i]->elem_restr, 13826e15d496SJeremy L Thompson CEED_TRANSPOSE, &restr_flops); CeedChk(ierr); 13836e15d496SJeremy L Thompson *flops += restr_flops; 13846e15d496SJeremy L Thompson ierr = CeedBasisGetFlopsEstimate(output_fields[i]->basis, CEED_TRANSPOSE, 13856e15d496SJeremy L Thompson op->qf->output_fields[i]->eval_mode, &basis_flops); CeedChk(ierr); 13866e15d496SJeremy L Thompson *flops += basis_flops * num_elem; 13876e15d496SJeremy L Thompson } 13886e15d496SJeremy L Thompson } 13896e15d496SJeremy L Thompson } 13906e15d496SJeremy L Thompson 13916e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 13926e15d496SJeremy L Thompson } 13936e15d496SJeremy L Thompson 13946e15d496SJeremy L Thompson /** 13953668ca4bSJeremy L Thompson @brief Get label for a registered QFunctionContext field, or `NULL` if no 13963668ca4bSJeremy L Thompson field has been registered with this `field_name`. 13973668ca4bSJeremy L Thompson 13983668ca4bSJeremy L Thompson @param[in] op CeedOperator 13993668ca4bSJeremy L Thompson @param[in] field_name Name of field to retrieve label 14003668ca4bSJeremy L Thompson @param[out] field_label Variable to field label 14013668ca4bSJeremy L Thompson 14023668ca4bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 14033668ca4bSJeremy L Thompson 14043668ca4bSJeremy L Thompson @ref User 14053668ca4bSJeremy L Thompson **/ 14063668ca4bSJeremy L Thompson int CeedOperatorContextGetFieldLabel(CeedOperator op, 14073668ca4bSJeremy L Thompson const char *field_name, 14083668ca4bSJeremy L Thompson CeedContextFieldLabel *field_label) { 14093668ca4bSJeremy L Thompson int ierr; 14103668ca4bSJeremy L Thompson 14113668ca4bSJeremy L Thompson bool is_composite; 14123668ca4bSJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 14133668ca4bSJeremy L Thompson if (is_composite) { 14143668ca4bSJeremy L Thompson // Check if composite label already created 14153668ca4bSJeremy L Thompson for (CeedInt i=0; i<op->num_context_labels; i++) { 14163668ca4bSJeremy L Thompson if (!strcmp(op->context_labels[i]->name, field_name)) { 14173668ca4bSJeremy L Thompson *field_label = op->context_labels[i]; 14183668ca4bSJeremy L Thompson return CEED_ERROR_SUCCESS; 14193668ca4bSJeremy L Thompson } 14203668ca4bSJeremy L Thompson } 14213668ca4bSJeremy L Thompson 14223668ca4bSJeremy L Thompson // Create composite label if needed 14233668ca4bSJeremy L Thompson CeedInt num_sub; 14243668ca4bSJeremy L Thompson CeedOperator *sub_operators; 14253668ca4bSJeremy L Thompson CeedContextFieldLabel new_field_label; 14263668ca4bSJeremy L Thompson 14273668ca4bSJeremy L Thompson ierr = CeedCalloc(1, &new_field_label); CeedChk(ierr); 14283668ca4bSJeremy L Thompson ierr = CeedOperatorGetNumSub(op, &num_sub); CeedChk(ierr); 14293668ca4bSJeremy L Thompson ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 14303668ca4bSJeremy L Thompson ierr = CeedCalloc(num_sub, &new_field_label->sub_labels); CeedChk(ierr); 14313668ca4bSJeremy L Thompson new_field_label->num_sub_labels = num_sub; 14323668ca4bSJeremy L Thompson 14333668ca4bSJeremy L Thompson bool label_found = false; 14343668ca4bSJeremy L Thompson for (CeedInt i=0; i<num_sub; i++) { 14353668ca4bSJeremy L Thompson if (sub_operators[i]->qf->ctx) { 14363668ca4bSJeremy L Thompson CeedContextFieldLabel new_field_label_i; 14373668ca4bSJeremy L Thompson ierr = CeedQFunctionContextGetFieldLabel(sub_operators[i]->qf->ctx, field_name, 14383668ca4bSJeremy L Thompson &new_field_label_i); CeedChk(ierr); 14393668ca4bSJeremy L Thompson if (new_field_label_i) { 14403668ca4bSJeremy L Thompson label_found = true; 14413668ca4bSJeremy L Thompson new_field_label->sub_labels[i] = new_field_label_i; 14423668ca4bSJeremy L Thompson new_field_label->name = new_field_label_i->name; 14433668ca4bSJeremy L Thompson new_field_label->description = new_field_label_i->description; 14447bfe0f0eSJeremy L Thompson if (new_field_label->type && 14457bfe0f0eSJeremy L Thompson new_field_label->type != new_field_label_i->type) { 14467bfe0f0eSJeremy L Thompson // LCOV_EXCL_START 14477bfe0f0eSJeremy L Thompson ierr = CeedFree(&new_field_label); CeedChk(ierr); 14487bfe0f0eSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 14497bfe0f0eSJeremy L Thompson "Incompatible field types on sub-operator contexts. " 14507bfe0f0eSJeremy L Thompson "%s != %s", 14517bfe0f0eSJeremy L Thompson CeedContextFieldTypes[new_field_label->type], 14527bfe0f0eSJeremy L Thompson CeedContextFieldTypes[new_field_label_i->type]); 14537bfe0f0eSJeremy L Thompson // LCOV_EXCL_STOP 14547bfe0f0eSJeremy L Thompson } else { 14557bfe0f0eSJeremy L Thompson new_field_label->type = new_field_label_i->type; 14567bfe0f0eSJeremy L Thompson } 14577bfe0f0eSJeremy L Thompson if (new_field_label->num_values != 0 && 14587bfe0f0eSJeremy L Thompson new_field_label->num_values != new_field_label_i->num_values) { 14597bfe0f0eSJeremy L Thompson // LCOV_EXCL_START 14607bfe0f0eSJeremy L Thompson ierr = CeedFree(&new_field_label); CeedChk(ierr); 14617bfe0f0eSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 14627bfe0f0eSJeremy L Thompson "Incompatible field number of values on sub-operator" 14637bfe0f0eSJeremy L Thompson " contexts. %ld != %ld", 14647bfe0f0eSJeremy L Thompson new_field_label->num_values, new_field_label_i->num_values); 14657bfe0f0eSJeremy L Thompson // LCOV_EXCL_STOP 14667bfe0f0eSJeremy L Thompson } else { 14677bfe0f0eSJeremy L Thompson new_field_label->num_values = new_field_label_i->num_values; 14687bfe0f0eSJeremy L Thompson } 14693668ca4bSJeremy L Thompson } 14703668ca4bSJeremy L Thompson } 14713668ca4bSJeremy L Thompson } 14723668ca4bSJeremy L Thompson if (!label_found) { 14733668ca4bSJeremy L Thompson // LCOV_EXCL_START 1474a48e5f43SJeremy L Thompson ierr = CeedFree(&new_field_label->sub_labels); CeedChk(ierr); 14753668ca4bSJeremy L Thompson ierr = CeedFree(&new_field_label); CeedChk(ierr); 14763668ca4bSJeremy L Thompson *field_label = NULL; 14773668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 14783668ca4bSJeremy L Thompson } else { 14793668ca4bSJeremy L Thompson // Move new composite label to operator 14803668ca4bSJeremy L Thompson if (op->num_context_labels == 0) { 14813668ca4bSJeremy L Thompson ierr = CeedCalloc(1, &op->context_labels); CeedChk(ierr); 14823668ca4bSJeremy L Thompson op->max_context_labels = 1; 14833668ca4bSJeremy L Thompson } else if (op->num_context_labels == op->max_context_labels) { 14843668ca4bSJeremy L Thompson ierr = CeedRealloc(2*op->num_context_labels, &op->context_labels); 14853668ca4bSJeremy L Thompson CeedChk(ierr); 14863668ca4bSJeremy L Thompson op->max_context_labels *= 2; 14873668ca4bSJeremy L Thompson } 14883668ca4bSJeremy L Thompson op->context_labels[op->num_context_labels] = new_field_label; 14893668ca4bSJeremy L Thompson *field_label = new_field_label; 14903668ca4bSJeremy L Thompson op->num_context_labels++; 14913668ca4bSJeremy L Thompson } 14923668ca4bSJeremy L Thompson 14933668ca4bSJeremy L Thompson return CEED_ERROR_SUCCESS; 14943668ca4bSJeremy L Thompson } else { 14953668ca4bSJeremy L Thompson return CeedQFunctionContextGetFieldLabel(op->qf->ctx, field_name, field_label); 14963668ca4bSJeremy L Thompson } 14973668ca4bSJeremy L Thompson } 14983668ca4bSJeremy L Thompson 14993668ca4bSJeremy L Thompson /** 1500d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field holding a double precision value. 1501d8dd9a91SJeremy L Thompson For composite operators, the value is set in all 1502d8dd9a91SJeremy L Thompson sub-operator QFunctionContexts that have a matching `field_name`. 1503d8dd9a91SJeremy L Thompson 1504d8dd9a91SJeremy L Thompson @param op CeedOperator 15053668ca4bSJeremy L Thompson @param field_label Label of field to register 15067bfe0f0eSJeremy L Thompson @param values Values to set 1507d8dd9a91SJeremy L Thompson 1508d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1509d8dd9a91SJeremy L Thompson 1510d8dd9a91SJeremy L Thompson @ref User 1511d8dd9a91SJeremy L Thompson **/ 15123668ca4bSJeremy L Thompson int CeedOperatorContextSetDouble(CeedOperator op, 15133668ca4bSJeremy L Thompson CeedContextFieldLabel field_label, 15147bfe0f0eSJeremy L Thompson double *values) { 15153668ca4bSJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_DOUBLE, 15167bfe0f0eSJeremy L Thompson values); 1517d8dd9a91SJeremy L Thompson } 1518d8dd9a91SJeremy L Thompson 1519d8dd9a91SJeremy L Thompson /** 1520d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field holding an int32 value. 1521d8dd9a91SJeremy L Thompson For composite operators, the value is set in all 1522d8dd9a91SJeremy L Thompson sub-operator QFunctionContexts that have a matching `field_name`. 1523d8dd9a91SJeremy L Thompson 1524d8dd9a91SJeremy L Thompson @param op CeedOperator 15253668ca4bSJeremy L Thompson @param field_label Label of field to set 15267bfe0f0eSJeremy L Thompson @param values Values to set 1527d8dd9a91SJeremy L Thompson 1528d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1529d8dd9a91SJeremy L Thompson 1530d8dd9a91SJeremy L Thompson @ref User 1531d8dd9a91SJeremy L Thompson **/ 15323668ca4bSJeremy L Thompson int CeedOperatorContextSetInt32(CeedOperator op, 15333668ca4bSJeremy L Thompson CeedContextFieldLabel field_label, 15347bfe0f0eSJeremy L Thompson int *values) { 15353668ca4bSJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_INT32, 15367bfe0f0eSJeremy L Thompson values); 1537d8dd9a91SJeremy L Thompson } 1538d8dd9a91SJeremy L Thompson 1539d8dd9a91SJeremy L Thompson /** 15403bd813ffSjeremylt @brief Apply CeedOperator to a vector 1541d7b241e6Sjeremylt 1542d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 1543d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 1544d7b241e6Sjeremylt CeedOperatorSetField(). 1545d7b241e6Sjeremylt 1546f04ea552SJeremy L Thompson Note: Calling this function asserts that setup is complete 1547f04ea552SJeremy L Thompson and sets the CeedOperator as immutable. 1548f04ea552SJeremy L Thompson 1549d7b241e6Sjeremylt @param op CeedOperator to apply 15504cc79fe7SJed Brown @param[in] in CeedVector containing input state or @ref CEED_VECTOR_NONE if 155134138859Sjeremylt there are no active inputs 1552b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 15534cc79fe7SJed Brown distinct from @a in) or @ref CEED_VECTOR_NONE if there are no 155434138859Sjeremylt active outputs 1555d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 15564cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1557b11c1e72Sjeremylt 1558b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1559dfdf5a53Sjeremylt 15607a982d89SJeremy L. Thompson @ref User 1561b11c1e72Sjeremylt **/ 1562692c2638Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, 1563692c2638Sjeremylt CeedRequest *request) { 1564d7b241e6Sjeremylt int ierr; 1565e2f04181SAndrew T. Barker ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 1566d7b241e6Sjeremylt 1567d1d35e2fSjeremylt if (op->num_elem) { 1568250756a7Sjeremylt // Standard Operator 1569cae8b89aSjeremylt if (op->Apply) { 1570250756a7Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 1571cae8b89aSjeremylt } else { 1572cae8b89aSjeremylt // Zero all output vectors 1573250756a7Sjeremylt CeedQFunction qf = op->qf; 1574d1d35e2fSjeremylt for (CeedInt i=0; i<qf->num_output_fields; i++) { 1575d1d35e2fSjeremylt CeedVector vec = op->output_fields[i]->vec; 1576cae8b89aSjeremylt if (vec == CEED_VECTOR_ACTIVE) 1577cae8b89aSjeremylt vec = out; 1578cae8b89aSjeremylt if (vec != CEED_VECTOR_NONE) { 1579cae8b89aSjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1580cae8b89aSjeremylt } 1581cae8b89aSjeremylt } 1582250756a7Sjeremylt // Apply 1583250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1584250756a7Sjeremylt } 1585f04ea552SJeremy L Thompson } else if (op->is_composite) { 1586250756a7Sjeremylt // Composite Operator 1587250756a7Sjeremylt if (op->ApplyComposite) { 1588250756a7Sjeremylt ierr = op->ApplyComposite(op, in, out, request); CeedChk(ierr); 1589250756a7Sjeremylt } else { 1590d1d35e2fSjeremylt CeedInt num_suboperators; 1591d1d35e2fSjeremylt ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 1592d1d35e2fSjeremylt CeedOperator *sub_operators; 1593d1d35e2fSjeremylt ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 1594250756a7Sjeremylt 1595250756a7Sjeremylt // Zero all output vectors 1596250756a7Sjeremylt if (out != CEED_VECTOR_NONE) { 1597cae8b89aSjeremylt ierr = CeedVectorSetValue(out, 0.0); CeedChk(ierr); 1598cae8b89aSjeremylt } 1599d1d35e2fSjeremylt for (CeedInt i=0; i<num_suboperators; i++) { 1600d1d35e2fSjeremylt for (CeedInt j=0; j<sub_operators[i]->qf->num_output_fields; j++) { 1601d1d35e2fSjeremylt CeedVector vec = sub_operators[i]->output_fields[j]->vec; 1602250756a7Sjeremylt if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) { 1603250756a7Sjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1604250756a7Sjeremylt } 1605250756a7Sjeremylt } 1606250756a7Sjeremylt } 1607250756a7Sjeremylt // Apply 1608d1d35e2fSjeremylt for (CeedInt i=0; i<op->num_suboperators; i++) { 1609d1d35e2fSjeremylt ierr = CeedOperatorApplyAdd(op->sub_operators[i], in, out, request); 1610cae8b89aSjeremylt CeedChk(ierr); 1611cae8b89aSjeremylt } 1612cae8b89aSjeremylt } 1613250756a7Sjeremylt } 1614e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1615cae8b89aSjeremylt } 1616cae8b89aSjeremylt 1617cae8b89aSjeremylt /** 1618cae8b89aSjeremylt @brief Apply CeedOperator to a vector and add result to output vector 1619cae8b89aSjeremylt 1620cae8b89aSjeremylt This computes the action of the operator on the specified (active) input, 1621cae8b89aSjeremylt yielding its (active) output. All inputs and outputs must be specified using 1622cae8b89aSjeremylt CeedOperatorSetField(). 1623cae8b89aSjeremylt 1624cae8b89aSjeremylt @param op CeedOperator to apply 1625cae8b89aSjeremylt @param[in] in CeedVector containing input state or NULL if there are no 1626cae8b89aSjeremylt active inputs 1627cae8b89aSjeremylt @param[out] out CeedVector to sum in result of applying operator (must be 1628cae8b89aSjeremylt distinct from @a in) or NULL if there are no active outputs 1629cae8b89aSjeremylt @param request Address of CeedRequest for non-blocking completion, else 16304cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1631cae8b89aSjeremylt 1632cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 1633cae8b89aSjeremylt 16347a982d89SJeremy L. Thompson @ref User 1635cae8b89aSjeremylt **/ 1636cae8b89aSjeremylt int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, 1637cae8b89aSjeremylt CeedRequest *request) { 1638cae8b89aSjeremylt int ierr; 1639e2f04181SAndrew T. Barker ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 1640cae8b89aSjeremylt 1641d1d35e2fSjeremylt if (op->num_elem) { 1642250756a7Sjeremylt // Standard Operator 1643250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1644f04ea552SJeremy L Thompson } else if (op->is_composite) { 1645250756a7Sjeremylt // Composite Operator 1646250756a7Sjeremylt if (op->ApplyAddComposite) { 1647250756a7Sjeremylt ierr = op->ApplyAddComposite(op, in, out, request); CeedChk(ierr); 1648cae8b89aSjeremylt } else { 1649d1d35e2fSjeremylt CeedInt num_suboperators; 1650d1d35e2fSjeremylt ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 1651d1d35e2fSjeremylt CeedOperator *sub_operators; 1652d1d35e2fSjeremylt ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 1653250756a7Sjeremylt 1654d1d35e2fSjeremylt for (CeedInt i=0; i<num_suboperators; i++) { 1655d1d35e2fSjeremylt ierr = CeedOperatorApplyAdd(sub_operators[i], in, out, request); 1656cae8b89aSjeremylt CeedChk(ierr); 16571d7d2407SJeremy L Thompson } 1658250756a7Sjeremylt } 1659250756a7Sjeremylt } 1660e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1661d7b241e6Sjeremylt } 1662d7b241e6Sjeremylt 1663d7b241e6Sjeremylt /** 1664b11c1e72Sjeremylt @brief Destroy a CeedOperator 1665d7b241e6Sjeremylt 1666d7b241e6Sjeremylt @param op CeedOperator to destroy 1667b11c1e72Sjeremylt 1668b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1669dfdf5a53Sjeremylt 16707a982d89SJeremy L. Thompson @ref User 1671b11c1e72Sjeremylt **/ 1672d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 1673d7b241e6Sjeremylt int ierr; 1674d7b241e6Sjeremylt 1675d1d35e2fSjeremylt if (!*op || --(*op)->ref_count > 0) return CEED_ERROR_SUCCESS; 1676d7b241e6Sjeremylt if ((*op)->Destroy) { 1677d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 1678d7b241e6Sjeremylt } 1679fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 1680fe2413ffSjeremylt // Free fields 16813668ca4bSJeremy L Thompson for (CeedInt i=0; i<(*op)->num_fields; i++) 1682d1d35e2fSjeremylt if ((*op)->input_fields[i]) { 1683d1d35e2fSjeremylt if ((*op)->input_fields[i]->elem_restr != CEED_ELEMRESTRICTION_NONE) { 1684d1d35e2fSjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->input_fields[i]->elem_restr); 168571352a93Sjeremylt CeedChk(ierr); 168615910d16Sjeremylt } 1687d1d35e2fSjeremylt if ((*op)->input_fields[i]->basis != CEED_BASIS_COLLOCATED) { 1688d1d35e2fSjeremylt ierr = CeedBasisDestroy(&(*op)->input_fields[i]->basis); CeedChk(ierr); 168971352a93Sjeremylt } 1690d1d35e2fSjeremylt if ((*op)->input_fields[i]->vec != CEED_VECTOR_ACTIVE && 1691d1d35e2fSjeremylt (*op)->input_fields[i]->vec != CEED_VECTOR_NONE ) { 1692d1d35e2fSjeremylt ierr = CeedVectorDestroy(&(*op)->input_fields[i]->vec); CeedChk(ierr); 169371352a93Sjeremylt } 1694d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields[i]->field_name); CeedChk(ierr); 1695d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields[i]); CeedChk(ierr); 1696fe2413ffSjeremylt } 16973668ca4bSJeremy L Thompson for (CeedInt i=0; i<(*op)->num_fields; i++) 1698d1d35e2fSjeremylt if ((*op)->output_fields[i]) { 1699d1d35e2fSjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->output_fields[i]->elem_restr); 170071352a93Sjeremylt CeedChk(ierr); 1701d1d35e2fSjeremylt if ((*op)->output_fields[i]->basis != CEED_BASIS_COLLOCATED) { 1702d1d35e2fSjeremylt ierr = CeedBasisDestroy(&(*op)->output_fields[i]->basis); CeedChk(ierr); 170371352a93Sjeremylt } 1704d1d35e2fSjeremylt if ((*op)->output_fields[i]->vec != CEED_VECTOR_ACTIVE && 1705d1d35e2fSjeremylt (*op)->output_fields[i]->vec != CEED_VECTOR_NONE ) { 1706d1d35e2fSjeremylt ierr = CeedVectorDestroy(&(*op)->output_fields[i]->vec); CeedChk(ierr); 170771352a93Sjeremylt } 1708d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields[i]->field_name); CeedChk(ierr); 1709d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields[i]); CeedChk(ierr); 1710fe2413ffSjeremylt } 1711d1d35e2fSjeremylt // Destroy sub_operators 17123668ca4bSJeremy L Thompson for (CeedInt i=0; i<(*op)->num_suboperators; i++) 1713d1d35e2fSjeremylt if ((*op)->sub_operators[i]) { 1714d1d35e2fSjeremylt ierr = CeedOperatorDestroy(&(*op)->sub_operators[i]); CeedChk(ierr); 171552d6035fSJeremy L Thompson } 1716d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 1717d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 1718d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 17193668ca4bSJeremy L Thompson // Destroy any composite labels 17203668ca4bSJeremy L Thompson for (CeedInt i=0; i<(*op)->num_context_labels; i++) { 17213668ca4bSJeremy L Thompson ierr = CeedFree(&(*op)->context_labels[i]->sub_labels); CeedChk(ierr); 17223668ca4bSJeremy L Thompson ierr = CeedFree(&(*op)->context_labels[i]); CeedChk(ierr); 17233668ca4bSJeremy L Thompson } 17243668ca4bSJeremy L Thompson ierr = CeedFree(&(*op)->context_labels); CeedChk(ierr); 1725fe2413ffSjeremylt 17265107b09fSJeremy L Thompson // Destroy fallback 1727805fe78eSJeremy L Thompson ierr = CeedOperatorDestroy(&(*op)->op_fallback); CeedChk(ierr); 17285107b09fSJeremy L Thompson 1729ed9e99e6SJeremy L Thompson // Destroy assembly data 1730480fae85SJeremy L Thompson ierr = CeedQFunctionAssemblyDataDestroy(&(*op)->qf_assembled); CeedChk(ierr); 1731ed9e99e6SJeremy L Thompson ierr = CeedOperatorAssemblyDataDestroy(&(*op)->op_assembled); CeedChk(ierr); 173270a7ffb3SJeremy L Thompson 1733d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields); CeedChk(ierr); 1734d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields); CeedChk(ierr); 1735d1d35e2fSjeremylt ierr = CeedFree(&(*op)->sub_operators); CeedChk(ierr); 1736ea6b5821SJeremy L Thompson ierr = CeedFree(&(*op)->name); CeedChk(ierr); 1737d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 1738e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1739d7b241e6Sjeremylt } 1740d7b241e6Sjeremylt 1741d7b241e6Sjeremylt /// @} 1742