1d7b241e6Sjeremylt // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 2d7b241e6Sjeremylt // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 3d7b241e6Sjeremylt // reserved. See files LICENSE and NOTICE for details. 4d7b241e6Sjeremylt // 5d7b241e6Sjeremylt // This file is part of CEED, a collection of benchmarks, miniapps, software 6d7b241e6Sjeremylt // libraries and APIs for efficient high-order finite element and spectral 7d7b241e6Sjeremylt // element discretizations for exascale applications. For more information and 8d7b241e6Sjeremylt // source code availability see http://github.com/ceed. 9d7b241e6Sjeremylt // 10d7b241e6Sjeremylt // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 11d7b241e6Sjeremylt // a collaborative effort of two U.S. Department of Energy organizations (Office 12d7b241e6Sjeremylt // of Science and the National Nuclear Security Administration) responsible for 13d7b241e6Sjeremylt // the planning and preparation of a capable exascale ecosystem, including 14d7b241e6Sjeremylt // software, applications, hardware, advanced system engineering and early 15d7b241e6Sjeremylt // testbed platforms, in support of the nation's exascale computing imperative. 16d7b241e6Sjeremylt 17d7b241e6Sjeremylt #include <ceed-impl.h> 18d863ab9bSjeremylt #include <ceed-backend.h> 19d7b241e6Sjeremylt #include <string.h> 20d7b241e6Sjeremylt 21dfdf5a53Sjeremylt /// @file 22dfdf5a53Sjeremylt /// Implementation of public CeedOperator interfaces 23dfdf5a53Sjeremylt /// 24dfdf5a53Sjeremylt /// @addtogroup CeedOperator 25dfdf5a53Sjeremylt /// @{ 26d7b241e6Sjeremylt 27d7b241e6Sjeremylt /** 280219ea01SJeremy L Thompson @brief Create a CeedOperator and associate a CeedQFunction. A CeedBasis and 290219ea01SJeremy L Thompson CeedElemRestriction can be associated with CeedQFunction fields with 300219ea01SJeremy L Thompson \ref CeedOperatorSetField. 31d7b241e6Sjeremylt 32b11c1e72Sjeremylt @param ceed A Ceed object where the CeedOperator will be created 33d7b241e6Sjeremylt @param qf QFunction defining the action of the operator at quadrature points 34d7b241e6Sjeremylt @param dqf QFunction defining the action of the Jacobian of @a qf (or NULL) 35d7b241e6Sjeremylt @param dqfT QFunction defining the action of the transpose of the Jacobian 36d7b241e6Sjeremylt of @a qf (or NULL) 37b11c1e72Sjeremylt @param[out] op Address of the variable where the newly created 38b11c1e72Sjeremylt CeedOperator will be stored 39b11c1e72Sjeremylt 40b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 41dfdf5a53Sjeremylt 42dfdf5a53Sjeremylt @ref Basic 43d7b241e6Sjeremylt */ 44d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, 45d7b241e6Sjeremylt CeedQFunction dqfT, CeedOperator *op) { 46d7b241e6Sjeremylt int ierr; 47d7b241e6Sjeremylt 485fe0d4faSjeremylt if (!ceed->OperatorCreate) { 495fe0d4faSjeremylt Ceed delegate; 50aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 515fe0d4faSjeremylt 525fe0d4faSjeremylt if (!delegate) 53c042f62fSJeremy L Thompson // LCOV_EXCL_START 545fe0d4faSjeremylt return CeedError(ceed, 1, "Backend does not support OperatorCreate"); 55c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 565fe0d4faSjeremylt 575fe0d4faSjeremylt ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr); 585fe0d4faSjeremylt return 0; 595fe0d4faSjeremylt } 605fe0d4faSjeremylt 61d7b241e6Sjeremylt ierr = CeedCalloc(1,op); CeedChk(ierr); 62d7b241e6Sjeremylt (*op)->ceed = ceed; 63d7b241e6Sjeremylt ceed->refcount++; 64d7b241e6Sjeremylt (*op)->refcount = 1; 65d7b241e6Sjeremylt (*op)->qf = qf; 66d7b241e6Sjeremylt qf->refcount++; 67d7b241e6Sjeremylt (*op)->dqf = dqf; 68d7b241e6Sjeremylt if (dqf) dqf->refcount++; 69d7b241e6Sjeremylt (*op)->dqfT = dqfT; 70d7b241e6Sjeremylt if (dqfT) dqfT->refcount++; 71fe2413ffSjeremylt ierr = CeedCalloc(16, &(*op)->inputfields); CeedChk(ierr); 72fe2413ffSjeremylt ierr = CeedCalloc(16, &(*op)->outputfields); CeedChk(ierr); 73d7b241e6Sjeremylt ierr = ceed->OperatorCreate(*op); CeedChk(ierr); 74d7b241e6Sjeremylt return 0; 75d7b241e6Sjeremylt } 76d7b241e6Sjeremylt 77d7b241e6Sjeremylt /** 7852d6035fSJeremy L Thompson @brief Create an operator that composes the action of several operators 7952d6035fSJeremy L Thompson 8052d6035fSJeremy L Thompson @param ceed A Ceed object where the CeedOperator will be created 8152d6035fSJeremy L Thompson @param[out] op Address of the variable where the newly created 8252d6035fSJeremy L Thompson Composite CeedOperator will be stored 8352d6035fSJeremy L Thompson 8452d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 8552d6035fSJeremy L Thompson 8652d6035fSJeremy L Thompson @ref Basic 8752d6035fSJeremy L Thompson */ 8852d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) { 8952d6035fSJeremy L Thompson int ierr; 9052d6035fSJeremy L Thompson 9152d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 9252d6035fSJeremy L Thompson Ceed delegate; 93aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 9452d6035fSJeremy L Thompson 9552d6035fSJeremy L Thompson if (!delegate) 96c042f62fSJeremy L Thompson // LCOV_EXCL_START 971d102b48SJeremy L Thompson return CeedError(ceed, 1, "Backend does not support " 981d102b48SJeremy L Thompson "CompositeOperatorCreate"); 99c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 10052d6035fSJeremy L Thompson 10152d6035fSJeremy L Thompson ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr); 10252d6035fSJeremy L Thompson return 0; 10352d6035fSJeremy L Thompson } 10452d6035fSJeremy L Thompson 10552d6035fSJeremy L Thompson ierr = CeedCalloc(1,op); CeedChk(ierr); 10652d6035fSJeremy L Thompson (*op)->ceed = ceed; 10752d6035fSJeremy L Thompson ceed->refcount++; 10852d6035fSJeremy L Thompson (*op)->composite = true; 10952d6035fSJeremy L Thompson ierr = CeedCalloc(16, &(*op)->suboperators); CeedChk(ierr); 11052d6035fSJeremy L Thompson ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr); 11152d6035fSJeremy L Thompson return 0; 11252d6035fSJeremy L Thompson } 11352d6035fSJeremy L Thompson 11452d6035fSJeremy L Thompson /** 115b11c1e72Sjeremylt @brief Provide a field to a CeedOperator for use by its CeedQFunction 116d7b241e6Sjeremylt 117d7b241e6Sjeremylt This function is used to specify both active and passive fields to a 118d7b241e6Sjeremylt CeedOperator. For passive fields, a vector @arg v must be provided. Passive 119d7b241e6Sjeremylt fields can inputs or outputs (updated in-place when operator is applied). 120d7b241e6Sjeremylt 121d7b241e6Sjeremylt Active fields must be specified using this function, but their data (in a 122d7b241e6Sjeremylt CeedVector) is passed in CeedOperatorApply(). There can be at most one active 123d7b241e6Sjeremylt input and at most one active output. 124d7b241e6Sjeremylt 1258c91a0c9SJeremy L Thompson @param op CeedOperator on which to provide the field 1268795c945Sjeremylt @param fieldname Name of the field (to be matched with the name used by 1278795c945Sjeremylt CeedQFunction) 128b11c1e72Sjeremylt @param r CeedElemRestriction 129b0e29e78Sjeremylt @param lmode CeedTransposeMode which specifies the ordering of the 130b0e29e78Sjeremylt components of the l-vector used by this CeedOperatorField, 131b0e29e78Sjeremylt CEED_NOTRANSPOSE indicates the component is the 132b0e29e78Sjeremylt outermost index and CEED_TRANSPOSE indicates the component 133b0e29e78Sjeremylt is the innermost index in ordering of the l-vector 134783c99b3SValeria Barra @param b CeedBasis in which the field resides or CEED_BASIS_COLLOCATED 135b11c1e72Sjeremylt if collocated with quadrature points 136b11c1e72Sjeremylt @param v CeedVector to be used by CeedOperator or CEED_VECTOR_ACTIVE 137b11c1e72Sjeremylt if field is active or CEED_VECTOR_NONE if using 1388c91a0c9SJeremy L Thompson CEED_EVAL_WEIGHT in the QFunction 139b11c1e72Sjeremylt 140b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 141dfdf5a53Sjeremylt 142dfdf5a53Sjeremylt @ref Basic 143b11c1e72Sjeremylt **/ 144d7b241e6Sjeremylt int CeedOperatorSetField(CeedOperator op, const char *fieldname, 1454dccadb6Sjeremylt CeedElemRestriction r, CeedTransposeMode lmode, 1464dccadb6Sjeremylt CeedBasis b, CeedVector v) { 147d7b241e6Sjeremylt int ierr; 14852d6035fSJeremy L Thompson if (op->composite) 149c042f62fSJeremy L Thompson // LCOV_EXCL_START 15052d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Cannot add field to composite operator."); 151c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1528b067b84SJed Brown if (!r) 153c042f62fSJeremy L Thompson // LCOV_EXCL_START 154c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, 155c042f62fSJeremy L Thompson "ElemRestriction r for field \"%s\" must be non-NULL.", 156c042f62fSJeremy L Thompson fieldname); 157c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1588b067b84SJed Brown if (!b) 159c042f62fSJeremy L Thompson // LCOV_EXCL_START 160c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Basis b for field \"%s\" must be non-NULL.", 161c042f62fSJeremy L Thompson fieldname); 162c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1638b067b84SJed Brown if (!v) 164c042f62fSJeremy L Thompson // LCOV_EXCL_START 165c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Vector v for field \"%s\" must be non-NULL.", 166c042f62fSJeremy L Thompson fieldname); 167c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 16852d6035fSJeremy L Thompson 169d7b241e6Sjeremylt CeedInt numelements; 170d7b241e6Sjeremylt ierr = CeedElemRestrictionGetNumElements(r, &numelements); CeedChk(ierr); 171*2cb0afc5Sjeremylt if (op->hasrestriction && op->numelements != numelements) 172c042f62fSJeremy L Thompson // LCOV_EXCL_START 173d7b241e6Sjeremylt return CeedError(op->ceed, 1, 1741d102b48SJeremy L Thompson "ElemRestriction with %d elements incompatible with prior " 1751d102b48SJeremy L Thompson "%d elements", numelements, op->numelements); 176c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 177d7b241e6Sjeremylt op->numelements = numelements; 178*2cb0afc5Sjeremylt op->hasrestriction = true; // Restriction set, but numelements may be 0 179d7b241e6Sjeremylt 180783c99b3SValeria Barra if (b != CEED_BASIS_COLLOCATED) { 181d7b241e6Sjeremylt CeedInt numqpoints; 182d7b241e6Sjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &numqpoints); CeedChk(ierr); 183d7b241e6Sjeremylt if (op->numqpoints && op->numqpoints != numqpoints) 184c042f62fSJeremy L Thompson // LCOV_EXCL_START 1851d102b48SJeremy L Thompson return CeedError(op->ceed, 1, "Basis with %d quadrature points " 1861d102b48SJeremy L Thompson "incompatible with prior %d points", numqpoints, 1871d102b48SJeremy L Thompson op->numqpoints); 188c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 189d7b241e6Sjeremylt op->numqpoints = numqpoints; 190d7b241e6Sjeremylt } 191d1bcdac9Sjeremylt CeedOperatorField *ofield; 192d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numinputfields; i++) { 193fe2413ffSjeremylt if (!strcmp(fieldname, (*op->qf->inputfields[i]).fieldname)) { 194d7b241e6Sjeremylt ofield = &op->inputfields[i]; 195d7b241e6Sjeremylt goto found; 196d7b241e6Sjeremylt } 197d7b241e6Sjeremylt } 198d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numoutputfields; i++) { 199fe2413ffSjeremylt if (!strcmp(fieldname, (*op->qf->outputfields[i]).fieldname)) { 200d7b241e6Sjeremylt ofield = &op->outputfields[i]; 201d7b241e6Sjeremylt goto found; 202d7b241e6Sjeremylt } 203d7b241e6Sjeremylt } 204c042f62fSJeremy L Thompson // LCOV_EXCL_START 205d7b241e6Sjeremylt return CeedError(op->ceed, 1, "QFunction has no knowledge of field '%s'", 206d7b241e6Sjeremylt fieldname); 207c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 208d7b241e6Sjeremylt found: 209fe2413ffSjeremylt ierr = CeedCalloc(1, ofield); CeedChk(ierr); 210fe2413ffSjeremylt (*ofield)->Erestrict = r; 21171352a93Sjeremylt r->refcount += 1; 212fe2413ffSjeremylt (*ofield)->lmode = lmode; 213fe2413ffSjeremylt (*ofield)->basis = b; 21471352a93Sjeremylt if (b != CEED_BASIS_COLLOCATED) 21571352a93Sjeremylt b->refcount += 1; 216fe2413ffSjeremylt (*ofield)->vec = v; 21771352a93Sjeremylt if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE) 21871352a93Sjeremylt v->refcount += 1; 219d7b241e6Sjeremylt op->nfields += 1; 220d7b241e6Sjeremylt return 0; 221d7b241e6Sjeremylt } 222d7b241e6Sjeremylt 223d7b241e6Sjeremylt /** 22452d6035fSJeremy L Thompson @brief Add a sub-operator to a composite CeedOperator 225288c0443SJeremy L Thompson 226288c0443SJeremy L Thompson @param[out] compositeop Address of the composite CeedOperator 227288c0443SJeremy L Thompson @param subop Address of the sub-operator CeedOperator 22852d6035fSJeremy L Thompson 22952d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 23052d6035fSJeremy L Thompson 23152d6035fSJeremy L Thompson @ref Basic 23252d6035fSJeremy L Thompson */ 23352d6035fSJeremy L Thompson int CeedCompositeOperatorAddSub(CeedOperator compositeop, 23452d6035fSJeremy L Thompson CeedOperator subop) { 23552d6035fSJeremy L Thompson if (!compositeop->composite) 236c042f62fSJeremy L Thompson // LCOV_EXCL_START 2371d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "CeedOperator is not a composite " 2381d102b48SJeremy L Thompson "operator"); 239c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 24052d6035fSJeremy L Thompson 24152d6035fSJeremy L Thompson if (compositeop->numsub == CEED_COMPOSITE_MAX) 242c042f62fSJeremy L Thompson // LCOV_EXCL_START 2431d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "Cannot add additional suboperators"); 244c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 24552d6035fSJeremy L Thompson 24652d6035fSJeremy L Thompson compositeop->suboperators[compositeop->numsub] = subop; 24752d6035fSJeremy L Thompson subop->refcount++; 24852d6035fSJeremy L Thompson compositeop->numsub++; 24952d6035fSJeremy L Thompson return 0; 25052d6035fSJeremy L Thompson } 25152d6035fSJeremy L Thompson 25252d6035fSJeremy L Thompson /** 2531d102b48SJeremy L Thompson @brief Assemble a linear CeedQFunction associated with a CeedOperator 2541d102b48SJeremy L Thompson 2551d102b48SJeremy L Thompson This returns a CeedVector containing a matrix at each quadrature point 2561d102b48SJeremy L Thompson providing the action of the CeedQFunction associated with the CeedOperator. 2571d102b48SJeremy L Thompson The vector 'assembled' is of shape 2581d102b48SJeremy L Thompson [num_elements, num_input_fields, num_output_fields, num_quad_points] 2591d102b48SJeremy L Thompson and contains column-major matrices representing the action of the 2601d102b48SJeremy L Thompson CeedQFunction for a corresponding quadrature point on an element. Inputs and 2611d102b48SJeremy L Thompson outputs are in the order provided by the user when adding CeedOperator fields. 2621d102b48SJeremy L Thompson For example, a QFunction with inputs 'u' and 'gradu' and outputs 'gradv' and 2631d102b48SJeremy L Thompson 'v', provided in that order, would result in an assembled QFunction that 2641d102b48SJeremy L Thompson consists of (1 + dim) x (dim + 1) matrices at each quadrature point acting 2651d102b48SJeremy L Thompson on the input [u, du_0, du_1] and producing the output [dv_0, dv_1, v]. 2661d102b48SJeremy L Thompson 2671d102b48SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 2681d102b48SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedQFunction at 2691d102b48SJeremy L Thompson quadrature points 2701d102b48SJeremy L Thompson @param[out] rstr CeedElemRestriction for CeedVector containing assembled 2711d102b48SJeremy L Thompson CeedQFunction 2721d102b48SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 2731d102b48SJeremy L Thompson CEED_REQUEST_IMMEDIATE 2741d102b48SJeremy L Thompson 2751d102b48SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2761d102b48SJeremy L Thompson 277b7ec98d8SJeremy L Thompson @ref Basic 2781d102b48SJeremy L Thompson **/ 2791d102b48SJeremy L Thompson int CeedOperatorAssembleLinearQFunction(CeedOperator op, CeedVector *assembled, 2807f823360Sjeremylt CeedElemRestriction *rstr, 2817f823360Sjeremylt CeedRequest *request) { 2821d102b48SJeremy L Thompson int ierr; 2831d102b48SJeremy L Thompson Ceed ceed = op->ceed; 2841d102b48SJeremy L Thompson CeedQFunction qf = op->qf; 2851d102b48SJeremy L Thompson 2861d102b48SJeremy L Thompson if (op->composite) { 287138d4072Sjeremylt // LCOV_EXCL_START 2881d102b48SJeremy L Thompson return CeedError(ceed, 1, "Cannot assemble QFunction for composite operator"); 289138d4072Sjeremylt // LCOV_EXCL_STOP 2901d102b48SJeremy L Thompson } else { 2911d102b48SJeremy L Thompson if (op->nfields == 0) 292138d4072Sjeremylt // LCOV_EXCL_START 2931d102b48SJeremy L Thompson return CeedError(ceed, 1, "No operator fields set"); 294138d4072Sjeremylt // LCOV_EXCL_STOP 2951d102b48SJeremy L Thompson if (op->nfields < qf->numinputfields + qf->numoutputfields) 296138d4072Sjeremylt // LCOV_EXCL_START 2971d102b48SJeremy L Thompson return CeedError( ceed, 1, "Not all operator fields set"); 298138d4072Sjeremylt // LCOV_EXCL_STOP 299*2cb0afc5Sjeremylt if (!op->hasrestriction) 300138d4072Sjeremylt // LCOV_EXCL_START 3011d102b48SJeremy L Thompson return CeedError(ceed, 1, "At least one restriction required"); 302138d4072Sjeremylt // LCOV_EXCL_STOP 3031d102b48SJeremy L Thompson if (op->numqpoints == 0) 304138d4072Sjeremylt // LCOV_EXCL_START 3051d102b48SJeremy L Thompson return CeedError(ceed, 1, "At least one non-collocated basis required"); 306138d4072Sjeremylt // LCOV_EXCL_STOP 3071d102b48SJeremy L Thompson } 3081d102b48SJeremy L Thompson ierr = op->AssembleLinearQFunction(op, assembled, rstr, request); 3091d102b48SJeremy L Thompson CeedChk(ierr); 3101d102b48SJeremy L Thompson return 0; 3111d102b48SJeremy L Thompson } 3121d102b48SJeremy L Thompson 3131d102b48SJeremy L Thompson /** 314b7ec98d8SJeremy L Thompson @brief Assemble the diagonal of a square linear Operator 315b7ec98d8SJeremy L Thompson 316b7ec98d8SJeremy L Thompson This returns a CeedVector containing the diagonal of a linear CeedOperator. 317b7ec98d8SJeremy L Thompson 318b7ec98d8SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 319b7ec98d8SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedOperator diagonal 320b7ec98d8SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 321b7ec98d8SJeremy L Thompson CEED_REQUEST_IMMEDIATE 322b7ec98d8SJeremy L Thompson 323b7ec98d8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 324b7ec98d8SJeremy L Thompson 325b7ec98d8SJeremy L Thompson @ref Basic 326b7ec98d8SJeremy L Thompson **/ 3277f823360Sjeremylt int CeedOperatorAssembleLinearDiagonal(CeedOperator op, CeedVector *assembled, 3287f823360Sjeremylt CeedRequest *request) { 329b7ec98d8SJeremy L Thompson int ierr; 330b7ec98d8SJeremy L Thompson Ceed ceed = op->ceed; 331b7ec98d8SJeremy L Thompson CeedQFunction qf = op->qf; 332b7ec98d8SJeremy L Thompson 333b7ec98d8SJeremy L Thompson if (op->composite) { 334b7ec98d8SJeremy L Thompson // LCOV_EXCL_START 335b7ec98d8SJeremy L Thompson return CeedError(ceed, 1, "Cannot assemble QFunction for composite operator"); 336b7ec98d8SJeremy L Thompson // LCOV_EXCL_STOP 337b7ec98d8SJeremy L Thompson } else { 338b7ec98d8SJeremy L Thompson if (op->nfields == 0) 339b7ec98d8SJeremy L Thompson // LCOV_EXCL_START 340b7ec98d8SJeremy L Thompson return CeedError(ceed, 1, "No operator fields set"); 341b7ec98d8SJeremy L Thompson // LCOV_EXCL_STOP 342b7ec98d8SJeremy L Thompson if (op->nfields < qf->numinputfields + qf->numoutputfields) 343b7ec98d8SJeremy L Thompson // LCOV_EXCL_START 344b7ec98d8SJeremy L Thompson return CeedError( ceed, 1, "Not all operator fields set"); 345b7ec98d8SJeremy L Thompson // LCOV_EXCL_STOP 346*2cb0afc5Sjeremylt if (!op->hasrestriction) 347b7ec98d8SJeremy L Thompson // LCOV_EXCL_START 348b7ec98d8SJeremy L Thompson return CeedError(ceed, 1, "At least one restriction required"); 349b7ec98d8SJeremy L Thompson // LCOV_EXCL_STOP 350b7ec98d8SJeremy L Thompson if (op->numqpoints == 0) 351b7ec98d8SJeremy L Thompson // LCOV_EXCL_START 352b7ec98d8SJeremy L Thompson return CeedError(ceed, 1, "At least one non-collocated basis required"); 353b7ec98d8SJeremy L Thompson // LCOV_EXCL_STOP 354b7ec98d8SJeremy L Thompson } 355b7ec98d8SJeremy L Thompson 356b7ec98d8SJeremy L Thompson // Use backend version, if available 357b7ec98d8SJeremy L Thompson if (op->AssembleLinearDiagonal) { 358b7ec98d8SJeremy L Thompson ierr = op->AssembleLinearDiagonal(op, assembled, request); CeedChk(ierr); 359b7ec98d8SJeremy L Thompson return 0; 360b7ec98d8SJeremy L Thompson } 361b7ec98d8SJeremy L Thompson 362b7ec98d8SJeremy L Thompson // Assemble QFunction 363b7ec98d8SJeremy L Thompson CeedVector assembledqf; 364b7ec98d8SJeremy L Thompson CeedElemRestriction rstr; 365b7ec98d8SJeremy L Thompson ierr = CeedOperatorAssembleLinearQFunction(op, &assembledqf, &rstr, request); 366b7ec98d8SJeremy L Thompson CeedChk(ierr); 367b7ec98d8SJeremy L Thompson ierr = CeedElemRestrictionDestroy(&rstr); CeedChk(ierr); 368b7ec98d8SJeremy L Thompson 369b7ec98d8SJeremy L Thompson // Determine active input basis 370112e3f70Sjeremylt CeedInt numemodein = 0, ncomp, dim = 1; 371b7ec98d8SJeremy L Thompson CeedEvalMode *emodein = NULL; 372112e3f70Sjeremylt CeedBasis basisin = NULL; 373112e3f70Sjeremylt CeedElemRestriction rstrin = NULL; 374b7ec98d8SJeremy L Thompson for (CeedInt i=0; i<qf->numinputfields; i++) 375b7ec98d8SJeremy L Thompson if (op->inputfields[i]->vec == CEED_VECTOR_ACTIVE) { 376b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetBasis(op->inputfields[i], &basisin); 377b7ec98d8SJeremy L Thompson CeedChk(ierr); 378b7ec98d8SJeremy L Thompson ierr = CeedBasisGetNumComponents(basisin, &ncomp); CeedChk(ierr); 379b7ec98d8SJeremy L Thompson ierr = CeedBasisGetDimension(basisin, &dim); CeedChk(ierr); 380b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetElemRestriction(op->inputfields[i], &rstrin); 381b7ec98d8SJeremy L Thompson CeedChk(ierr); 382b7ec98d8SJeremy L Thompson CeedEvalMode emode; 383b7ec98d8SJeremy L Thompson ierr = CeedQFunctionFieldGetEvalMode(qf->inputfields[i], &emode); 384b7ec98d8SJeremy L Thompson CeedChk(ierr); 385b7ec98d8SJeremy L Thompson switch (emode) { 386b7ec98d8SJeremy L Thompson case CEED_EVAL_NONE: 387b7ec98d8SJeremy L Thompson case CEED_EVAL_INTERP: 388b7ec98d8SJeremy L Thompson ierr = CeedRealloc(numemodein + 1, &emodein); CeedChk(ierr); 389b7ec98d8SJeremy L Thompson emodein[numemodein] = emode; 390b7ec98d8SJeremy L Thompson numemodein += 1; 391b7ec98d8SJeremy L Thompson break; 392b7ec98d8SJeremy L Thompson case CEED_EVAL_GRAD: 393b7ec98d8SJeremy L Thompson ierr = CeedRealloc(numemodein + dim, &emodein); CeedChk(ierr); 394b7ec98d8SJeremy L Thompson for (CeedInt d=0; d<dim; d++) 395b7ec98d8SJeremy L Thompson emodein[numemodein+d] = emode; 396b7ec98d8SJeremy L Thompson numemodein += dim; 397b7ec98d8SJeremy L Thompson break; 398b7ec98d8SJeremy L Thompson case CEED_EVAL_WEIGHT: 399b7ec98d8SJeremy L Thompson case CEED_EVAL_DIV: 400b7ec98d8SJeremy L Thompson case CEED_EVAL_CURL: 401b7ec98d8SJeremy L Thompson break; // Caught by QF Assembly 402b7ec98d8SJeremy L Thompson } 403b7ec98d8SJeremy L Thompson } 404b7ec98d8SJeremy L Thompson 405b7ec98d8SJeremy L Thompson // Determine active output basis 406b7ec98d8SJeremy L Thompson CeedInt numemodeout = 0; 407b7ec98d8SJeremy L Thompson CeedEvalMode *emodeout = NULL; 408112e3f70Sjeremylt CeedBasis basisout = NULL; 409112e3f70Sjeremylt CeedElemRestriction rstrout = NULL; 410112e3f70Sjeremylt CeedTransposeMode lmodeout = CEED_NOTRANSPOSE; 411b7ec98d8SJeremy L Thompson for (CeedInt i=0; i<qf->numoutputfields; i++) 412b7ec98d8SJeremy L Thompson if (op->outputfields[i]->vec == CEED_VECTOR_ACTIVE) { 413b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetBasis(op->outputfields[i], &basisout); 414b7ec98d8SJeremy L Thompson CeedChk(ierr); 415b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetElemRestriction(op->outputfields[i], &rstrout); 416b7ec98d8SJeremy L Thompson CeedChk(ierr); 417b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetLMode(op->outputfields[i], &lmodeout); 418b7ec98d8SJeremy L Thompson CeedChk(ierr); 419b7ec98d8SJeremy L Thompson CeedEvalMode emode; 420b7ec98d8SJeremy L Thompson ierr = CeedQFunctionFieldGetEvalMode(qf->outputfields[i], &emode); 421b7ec98d8SJeremy L Thompson CeedChk(ierr); 422b7ec98d8SJeremy L Thompson switch (emode) { 423b7ec98d8SJeremy L Thompson case CEED_EVAL_NONE: 424b7ec98d8SJeremy L Thompson case CEED_EVAL_INTERP: 425b7ec98d8SJeremy L Thompson ierr = CeedRealloc(numemodeout + 1, &emodeout); CeedChk(ierr); 426b7ec98d8SJeremy L Thompson emodeout[numemodeout] = emode; 427b7ec98d8SJeremy L Thompson numemodeout += 1; 428b7ec98d8SJeremy L Thompson break; 429b7ec98d8SJeremy L Thompson case CEED_EVAL_GRAD: 430b7ec98d8SJeremy L Thompson ierr = CeedRealloc(numemodeout + dim, &emodeout); CeedChk(ierr); 431b7ec98d8SJeremy L Thompson for (CeedInt d=0; d<dim; d++) 432b7ec98d8SJeremy L Thompson emodeout[numemodeout+d] = emode; 433b7ec98d8SJeremy L Thompson numemodeout += dim; 434b7ec98d8SJeremy L Thompson break; 435b7ec98d8SJeremy L Thompson case CEED_EVAL_WEIGHT: 436b7ec98d8SJeremy L Thompson case CEED_EVAL_DIV: 437b7ec98d8SJeremy L Thompson case CEED_EVAL_CURL: 438b7ec98d8SJeremy L Thompson break; // Caught by QF Assembly 439b7ec98d8SJeremy L Thompson } 440b7ec98d8SJeremy L Thompson } 441b7ec98d8SJeremy L Thompson 442b7ec98d8SJeremy L Thompson // Create diagonal vector 443b7ec98d8SJeremy L Thompson CeedVector elemdiag; 444b7ec98d8SJeremy L Thompson ierr = CeedElemRestrictionCreateVector(rstrin, assembled, &elemdiag); 445b7ec98d8SJeremy L Thompson CeedChk(ierr); 446b7ec98d8SJeremy L Thompson 447b7ec98d8SJeremy L Thompson // Assemble element operator diagonals 448b7ec98d8SJeremy L Thompson CeedScalar *elemdiagarray, *assembledqfarray; 449b7ec98d8SJeremy L Thompson ierr = CeedVectorSetValue(elemdiag, 0.0); CeedChk(ierr); 450b7ec98d8SJeremy L Thompson ierr = CeedVectorGetArray(elemdiag, CEED_MEM_HOST, &elemdiagarray); 451b7ec98d8SJeremy L Thompson CeedChk(ierr); 452b7ec98d8SJeremy L Thompson ierr = CeedVectorGetArray(assembledqf, CEED_MEM_HOST, &assembledqfarray); 453b7ec98d8SJeremy L Thompson CeedChk(ierr); 454b7ec98d8SJeremy L Thompson CeedInt nelem, nnodes, nqpts; 455b7ec98d8SJeremy L Thompson ierr = CeedElemRestrictionGetNumElements(rstrin, &nelem); CeedChk(ierr); 456b7ec98d8SJeremy L Thompson ierr = CeedBasisGetNumNodes(basisin, &nnodes); CeedChk(ierr); 457b7ec98d8SJeremy L Thompson ierr = CeedBasisGetNumQuadraturePoints(basisin, &nqpts); CeedChk(ierr); 458b7ec98d8SJeremy L Thompson // Compute the diagonal of B^T D B 459b7ec98d8SJeremy L Thompson // Each node, qpt pair 460b7ec98d8SJeremy L Thompson for (CeedInt n=0; n<nnodes; n++) 461b7ec98d8SJeremy L Thompson for (CeedInt q=0; q<nqpts; q++) { 462b7ec98d8SJeremy L Thompson CeedInt dout = -1; 463b7ec98d8SJeremy L Thompson // Each basis eval mode pair 464b7ec98d8SJeremy L Thompson for (CeedInt eout=0; eout<numemodeout; eout++) { 465b7ec98d8SJeremy L Thompson CeedScalar bt = 1.0; 466b7ec98d8SJeremy L Thompson if (emodeout[eout] == CEED_EVAL_GRAD) 467b7ec98d8SJeremy L Thompson dout += 1; 468b7ec98d8SJeremy L Thompson ierr = CeedBasisGetValue(basisout, emodeout[eout], q, n, dout, &bt); 469b7ec98d8SJeremy L Thompson CeedChk(ierr); 470b7ec98d8SJeremy L Thompson CeedInt din = -1; 471b7ec98d8SJeremy L Thompson for (CeedInt ein=0; ein<numemodein; ein++) { 472b7ec98d8SJeremy L Thompson CeedScalar b = 0.0; 473b7ec98d8SJeremy L Thompson if (emodein[ein] == CEED_EVAL_GRAD) 474b7ec98d8SJeremy L Thompson din += 1; 475b7ec98d8SJeremy L Thompson ierr = CeedBasisGetValue(basisin, emodein[ein], q, n, din, &b); 476b7ec98d8SJeremy L Thompson CeedChk(ierr); 477b7ec98d8SJeremy L Thompson // Each element and component 478b7ec98d8SJeremy L Thompson for (CeedInt e=0; e<nelem; e++) 479b7ec98d8SJeremy L Thompson for (CeedInt cout=0; cout<ncomp; cout++) { 480b7ec98d8SJeremy L Thompson CeedScalar db = 0.0; 481b7ec98d8SJeremy L Thompson for (CeedInt cin=0; cin<ncomp; cin++) 482b7ec98d8SJeremy L Thompson db += assembledqfarray[((((e*numemodein+ein)*ncomp+cin)* 483b7ec98d8SJeremy L Thompson numemodeout+eout)*ncomp+cout)*nqpts+q]*b; 484b7ec98d8SJeremy L Thompson elemdiagarray[(e*ncomp+cout)*nnodes+n] += bt * db; 485b7ec98d8SJeremy L Thompson } 486b7ec98d8SJeremy L Thompson } 487b7ec98d8SJeremy L Thompson } 488b7ec98d8SJeremy L Thompson } 489b7ec98d8SJeremy L Thompson 490b7ec98d8SJeremy L Thompson ierr = CeedVectorRestoreArray(elemdiag, &elemdiagarray); CeedChk(ierr); 491b7ec98d8SJeremy L Thompson ierr = CeedVectorRestoreArray(assembledqf, &assembledqfarray); CeedChk(ierr); 492b7ec98d8SJeremy L Thompson 493b7ec98d8SJeremy L Thompson // Assemble local operator diagonal 494b7ec98d8SJeremy L Thompson ierr = CeedVectorSetValue(*assembled, 0.0); CeedChk(ierr); 495b7ec98d8SJeremy L Thompson ierr = CeedElemRestrictionApply(rstrout, CEED_TRANSPOSE, lmodeout, elemdiag, 496b7ec98d8SJeremy L Thompson *assembled, request); CeedChk(ierr); 497b7ec98d8SJeremy L Thompson 498b7ec98d8SJeremy L Thompson // Cleanup 499b7ec98d8SJeremy L Thompson ierr = CeedVectorDestroy(&assembledqf); CeedChk(ierr); 500b7ec98d8SJeremy L Thompson ierr = CeedVectorDestroy(&elemdiag); CeedChk(ierr); 501b7ec98d8SJeremy L Thompson ierr = CeedFree(&emodein); CeedChk(ierr); 502b7ec98d8SJeremy L Thompson ierr = CeedFree(&emodeout); CeedChk(ierr); 503b7ec98d8SJeremy L Thompson 504b7ec98d8SJeremy L Thompson return 0; 505b7ec98d8SJeremy L Thompson } 506b7ec98d8SJeremy L Thompson 507b7ec98d8SJeremy L Thompson /** 508b11c1e72Sjeremylt @brief Apply CeedOperator to a vector 509d7b241e6Sjeremylt 510d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 511d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 512d7b241e6Sjeremylt CeedOperatorSetField(). 513d7b241e6Sjeremylt 514d7b241e6Sjeremylt @param op CeedOperator to apply 515b11c1e72Sjeremylt @param[in] in CeedVector containing input state or NULL if there are no 516b11c1e72Sjeremylt active inputs 517b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 518d7b241e6Sjeremylt distinct from @a in) or NULL if there are no active outputs 519d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 520d7b241e6Sjeremylt CEED_REQUEST_IMMEDIATE 521b11c1e72Sjeremylt 522b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 523dfdf5a53Sjeremylt 524dfdf5a53Sjeremylt @ref Basic 525b11c1e72Sjeremylt **/ 526d7b241e6Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, 527d7b241e6Sjeremylt CeedVector out, CeedRequest *request) { 528d7b241e6Sjeremylt int ierr; 529d7b241e6Sjeremylt Ceed ceed = op->ceed; 530d7b241e6Sjeremylt CeedQFunction qf = op->qf; 531d7b241e6Sjeremylt 53252d6035fSJeremy L Thompson if (op->composite) { 533c042f62fSJeremy L Thompson if (!op->numsub) 534c042f62fSJeremy L Thompson // LCOV_EXCL_START 535c042f62fSJeremy L Thompson return CeedError(ceed, 1, "No suboperators set"); 536c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 53752d6035fSJeremy L Thompson } else { 538c042f62fSJeremy L Thompson if (op->nfields == 0) 539c042f62fSJeremy L Thompson // LCOV_EXCL_START 540c042f62fSJeremy L Thompson return CeedError(ceed, 1, "No operator fields set"); 541c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 542c042f62fSJeremy L Thompson if (op->nfields < qf->numinputfields + qf->numoutputfields) 543c042f62fSJeremy L Thompson // LCOV_EXCL_START 544c042f62fSJeremy L Thompson return CeedError(ceed, 1, "Not all operator fields set"); 545c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 546*2cb0afc5Sjeremylt if (!op->hasrestriction) 547c042f62fSJeremy L Thompson // LCOV_EXCL_START 548c042f62fSJeremy L Thompson return CeedError(ceed, 1,"At least one restriction required"); 549c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 550c042f62fSJeremy L Thompson if (op->numqpoints == 0) 551c042f62fSJeremy L Thompson // LCOV_EXCL_START 552c042f62fSJeremy L Thompson return CeedError(ceed, 1,"At least one non-collocated basis required"); 553c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 55452d6035fSJeremy L Thompson } 5551d7d2407SJeremy L Thompson if (op->numelements || op->composite) { 556d7b241e6Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 5571d7d2407SJeremy L Thompson } 558d7b241e6Sjeremylt return 0; 559d7b241e6Sjeremylt } 560d7b241e6Sjeremylt 561d7b241e6Sjeremylt /** 5624ce2993fSjeremylt @brief Get the Ceed associated with a CeedOperator 5634ce2993fSjeremylt 5644ce2993fSjeremylt @param op CeedOperator 5654ce2993fSjeremylt @param[out] ceed Variable to store Ceed 5664ce2993fSjeremylt 5674ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5684ce2993fSjeremylt 56923617272Sjeremylt @ref Advanced 5704ce2993fSjeremylt **/ 5714ce2993fSjeremylt 5724ce2993fSjeremylt int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 5734ce2993fSjeremylt *ceed = op->ceed; 5744ce2993fSjeremylt return 0; 5754ce2993fSjeremylt } 5764ce2993fSjeremylt 5774ce2993fSjeremylt /** 5784ce2993fSjeremylt @brief Get the number of elements associated with a CeedOperator 5794ce2993fSjeremylt 5804ce2993fSjeremylt @param op CeedOperator 5814ce2993fSjeremylt @param[out] numelem Variable to store number of elements 5824ce2993fSjeremylt 5834ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5844ce2993fSjeremylt 58523617272Sjeremylt @ref Advanced 5864ce2993fSjeremylt **/ 5874ce2993fSjeremylt 5884ce2993fSjeremylt int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) { 58952d6035fSJeremy L Thompson if (op->composite) 590c042f62fSJeremy L Thompson // LCOV_EXCL_START 59152d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 592c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 59352d6035fSJeremy L Thompson 5944ce2993fSjeremylt *numelem = op->numelements; 5954ce2993fSjeremylt return 0; 5964ce2993fSjeremylt } 5974ce2993fSjeremylt 5984ce2993fSjeremylt /** 5994ce2993fSjeremylt @brief Get the number of quadrature points associated with a CeedOperator 6004ce2993fSjeremylt 6014ce2993fSjeremylt @param op CeedOperator 6024ce2993fSjeremylt @param[out] numqpts Variable to store vector number of quadrature points 6034ce2993fSjeremylt 6044ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6054ce2993fSjeremylt 60623617272Sjeremylt @ref Advanced 6074ce2993fSjeremylt **/ 6084ce2993fSjeremylt 6094ce2993fSjeremylt int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) { 61052d6035fSJeremy L Thompson if (op->composite) 611c042f62fSJeremy L Thompson // LCOV_EXCL_START 61252d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 613c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 61452d6035fSJeremy L Thompson 6154ce2993fSjeremylt *numqpts = op->numqpoints; 6164ce2993fSjeremylt return 0; 6174ce2993fSjeremylt } 6184ce2993fSjeremylt 6194ce2993fSjeremylt /** 6204ce2993fSjeremylt @brief Get the number of arguments associated with a CeedOperator 6214ce2993fSjeremylt 6224ce2993fSjeremylt @param op CeedOperator 6234ce2993fSjeremylt @param[out] numargs Variable to store vector number of arguments 6244ce2993fSjeremylt 6254ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6264ce2993fSjeremylt 62723617272Sjeremylt @ref Advanced 6284ce2993fSjeremylt **/ 6294ce2993fSjeremylt 6304ce2993fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) { 63152d6035fSJeremy L Thompson if (op->composite) 632c042f62fSJeremy L Thompson // LCOV_EXCL_START 63352d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operators"); 634c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 635c042f62fSJeremy L Thompson 6364ce2993fSjeremylt *numargs = op->nfields; 6374ce2993fSjeremylt return 0; 6384ce2993fSjeremylt } 6394ce2993fSjeremylt 6404ce2993fSjeremylt /** 6414ce2993fSjeremylt @brief Get the setup status of a CeedOperator 6424ce2993fSjeremylt 6434ce2993fSjeremylt @param op CeedOperator 644288c0443SJeremy L Thompson @param[out] setupdone Variable to store setup status 6454ce2993fSjeremylt 6464ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6474ce2993fSjeremylt 64823617272Sjeremylt @ref Advanced 6494ce2993fSjeremylt **/ 6504ce2993fSjeremylt 6514ce2993fSjeremylt int CeedOperatorGetSetupStatus(CeedOperator op, bool *setupdone) { 6524ce2993fSjeremylt *setupdone = op->setupdone; 6534ce2993fSjeremylt return 0; 6544ce2993fSjeremylt } 6554ce2993fSjeremylt 6564ce2993fSjeremylt /** 6574ce2993fSjeremylt @brief Get the QFunction associated with a CeedOperator 6584ce2993fSjeremylt 6594ce2993fSjeremylt @param op CeedOperator 6608c91a0c9SJeremy L Thompson @param[out] qf Variable to store QFunction 6614ce2993fSjeremylt 6624ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6634ce2993fSjeremylt 66423617272Sjeremylt @ref Advanced 6654ce2993fSjeremylt **/ 6664ce2993fSjeremylt 6674ce2993fSjeremylt int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 66852d6035fSJeremy L Thompson if (op->composite) 669c042f62fSJeremy L Thompson // LCOV_EXCL_START 67052d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 671c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 67252d6035fSJeremy L Thompson 6734ce2993fSjeremylt *qf = op->qf; 6744ce2993fSjeremylt return 0; 6754ce2993fSjeremylt } 6764ce2993fSjeremylt 6774ce2993fSjeremylt /** 67852d6035fSJeremy L Thompson @brief Get the number of suboperators associated with a CeedOperator 67952d6035fSJeremy L Thompson 68052d6035fSJeremy L Thompson @param op CeedOperator 68152d6035fSJeremy L Thompson @param[out] numsub Variable to store number of suboperators 68252d6035fSJeremy L Thompson 68352d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 68452d6035fSJeremy L Thompson 68552d6035fSJeremy L Thompson @ref Advanced 68652d6035fSJeremy L Thompson **/ 68752d6035fSJeremy L Thompson 68852d6035fSJeremy L Thompson int CeedOperatorGetNumSub(CeedOperator op, CeedInt *numsub) { 689c042f62fSJeremy L Thompson if (!op->composite) 690c042f62fSJeremy L Thompson // LCOV_EXCL_START 691c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 692c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 69352d6035fSJeremy L Thompson 69452d6035fSJeremy L Thompson *numsub = op->numsub; 69552d6035fSJeremy L Thompson return 0; 69652d6035fSJeremy L Thompson } 69752d6035fSJeremy L Thompson 69852d6035fSJeremy L Thompson /** 69952d6035fSJeremy L Thompson @brief Get the list of suboperators associated with a CeedOperator 70052d6035fSJeremy L Thompson 70152d6035fSJeremy L Thompson @param op CeedOperator 70252d6035fSJeremy L Thompson @param[out] suboperators Variable to store list of suboperators 70352d6035fSJeremy L Thompson 70452d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 70552d6035fSJeremy L Thompson 70652d6035fSJeremy L Thompson @ref Advanced 70752d6035fSJeremy L Thompson **/ 70852d6035fSJeremy L Thompson 70952d6035fSJeremy L Thompson int CeedOperatorGetSubList(CeedOperator op, CeedOperator* *suboperators) { 710c042f62fSJeremy L Thompson if (!op->composite) 711c042f62fSJeremy L Thompson // LCOV_EXCL_START 712c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 713c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 71452d6035fSJeremy L Thompson 71552d6035fSJeremy L Thompson *suboperators = op->suboperators; 71652d6035fSJeremy L Thompson return 0; 71752d6035fSJeremy L Thompson } 71852d6035fSJeremy L Thompson 71952d6035fSJeremy L Thompson /** 720fe2413ffSjeremylt @brief Set the backend data of a CeedOperator 721fe2413ffSjeremylt 722fe2413ffSjeremylt @param[out] op CeedOperator 723fe2413ffSjeremylt @param data Data to set 724fe2413ffSjeremylt 725fe2413ffSjeremylt @return An error code: 0 - success, otherwise - failure 726fe2413ffSjeremylt 727fe2413ffSjeremylt @ref Advanced 728fe2413ffSjeremylt **/ 729fe2413ffSjeremylt 730fe2413ffSjeremylt int CeedOperatorSetData(CeedOperator op, void* *data) { 731fe2413ffSjeremylt op->data = *data; 732fe2413ffSjeremylt return 0; 733fe2413ffSjeremylt } 734fe2413ffSjeremylt 735fe2413ffSjeremylt /** 7364ce2993fSjeremylt @brief Get the backend data of a CeedOperator 7374ce2993fSjeremylt 7384ce2993fSjeremylt @param op CeedOperator 7394ce2993fSjeremylt @param[out] data Variable to store data 7404ce2993fSjeremylt 7414ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7424ce2993fSjeremylt 74323617272Sjeremylt @ref Advanced 7444ce2993fSjeremylt **/ 7454ce2993fSjeremylt 7464ce2993fSjeremylt int CeedOperatorGetData(CeedOperator op, void* *data) { 7474ce2993fSjeremylt *data = op->data; 7484ce2993fSjeremylt return 0; 7494ce2993fSjeremylt } 7504ce2993fSjeremylt 7514ce2993fSjeremylt /** 7524ce2993fSjeremylt @brief Set the setup flag of a CeedOperator to True 7534ce2993fSjeremylt 7544ce2993fSjeremylt @param op CeedOperator 7554ce2993fSjeremylt 7564ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7574ce2993fSjeremylt 75823617272Sjeremylt @ref Advanced 7594ce2993fSjeremylt **/ 7604ce2993fSjeremylt 7614ce2993fSjeremylt int CeedOperatorSetSetupDone(CeedOperator op) { 7624ce2993fSjeremylt op->setupdone = 1; 7634ce2993fSjeremylt return 0; 7644ce2993fSjeremylt } 7654ce2993fSjeremylt 7664ce2993fSjeremylt /** 767d1bcdac9Sjeremylt @brief Get the CeedOperatorFields of a CeedOperator 768d1bcdac9Sjeremylt 769d1bcdac9Sjeremylt @param op CeedOperator 770d1bcdac9Sjeremylt @param[out] inputfields Variable to store inputfields 771d1bcdac9Sjeremylt @param[out] outputfields Variable to store outputfields 772d1bcdac9Sjeremylt 773d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 774d1bcdac9Sjeremylt 775d1bcdac9Sjeremylt @ref Advanced 776d1bcdac9Sjeremylt **/ 777d1bcdac9Sjeremylt 778d1bcdac9Sjeremylt int CeedOperatorGetFields(CeedOperator op, 779d1bcdac9Sjeremylt CeedOperatorField* *inputfields, 780d1bcdac9Sjeremylt CeedOperatorField* *outputfields) { 78152d6035fSJeremy L Thompson if (op->composite) 782c042f62fSJeremy L Thompson // LCOV_EXCL_START 78352d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 784c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 78552d6035fSJeremy L Thompson 786d1bcdac9Sjeremylt if (inputfields) *inputfields = op->inputfields; 787d1bcdac9Sjeremylt if (outputfields) *outputfields = op->outputfields; 788d1bcdac9Sjeremylt return 0; 789d1bcdac9Sjeremylt } 790d1bcdac9Sjeremylt 791d1bcdac9Sjeremylt /** 7924dccadb6Sjeremylt @brief Get the L vector CeedTransposeMode of a CeedOperatorField 7934dccadb6Sjeremylt 7944dccadb6Sjeremylt @param opfield CeedOperatorField 7954dccadb6Sjeremylt @param[out] lmode Variable to store CeedTransposeMode 7964dccadb6Sjeremylt 7974dccadb6Sjeremylt @return An error code: 0 - success, otherwise - failure 7984dccadb6Sjeremylt 7994dccadb6Sjeremylt @ref Advanced 8004dccadb6Sjeremylt **/ 8014dccadb6Sjeremylt 8024dccadb6Sjeremylt int CeedOperatorFieldGetLMode(CeedOperatorField opfield, 8034dccadb6Sjeremylt CeedTransposeMode *lmode) { 804fe2413ffSjeremylt *lmode = opfield->lmode; 8054dccadb6Sjeremylt return 0; 8062b8e417aSjeremylt } 8072b8e417aSjeremylt 8082b8e417aSjeremylt /** 809d1bcdac9Sjeremylt @brief Get the CeedElemRestriction of a CeedOperatorField 810d1bcdac9Sjeremylt 811d1bcdac9Sjeremylt @param opfield CeedOperatorField 812d1bcdac9Sjeremylt @param[out] rstr Variable to store CeedElemRestriction 813d1bcdac9Sjeremylt 814d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 815d1bcdac9Sjeremylt 816d1bcdac9Sjeremylt @ref Advanced 817d1bcdac9Sjeremylt **/ 818d1bcdac9Sjeremylt 819d1bcdac9Sjeremylt int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield, 820d1bcdac9Sjeremylt CeedElemRestriction *rstr) { 821fe2413ffSjeremylt *rstr = opfield->Erestrict; 822d1bcdac9Sjeremylt return 0; 823d1bcdac9Sjeremylt } 824d1bcdac9Sjeremylt 825d1bcdac9Sjeremylt /** 826d1bcdac9Sjeremylt @brief Get the CeedBasis of a CeedOperatorField 827d1bcdac9Sjeremylt 828d1bcdac9Sjeremylt @param opfield CeedOperatorField 829d1bcdac9Sjeremylt @param[out] basis Variable to store CeedBasis 830d1bcdac9Sjeremylt 831d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 832d1bcdac9Sjeremylt 833d1bcdac9Sjeremylt @ref Advanced 834d1bcdac9Sjeremylt **/ 835d1bcdac9Sjeremylt 836d1bcdac9Sjeremylt int CeedOperatorFieldGetBasis(CeedOperatorField opfield, 837d1bcdac9Sjeremylt CeedBasis *basis) { 838fe2413ffSjeremylt *basis = opfield->basis; 839d1bcdac9Sjeremylt return 0; 840d1bcdac9Sjeremylt } 841d1bcdac9Sjeremylt 842d1bcdac9Sjeremylt /** 843d1bcdac9Sjeremylt @brief Get the CeedVector of a CeedOperatorField 844d1bcdac9Sjeremylt 845d1bcdac9Sjeremylt @param opfield CeedOperatorField 846d1bcdac9Sjeremylt @param[out] vec Variable to store CeedVector 847d1bcdac9Sjeremylt 848d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 849d1bcdac9Sjeremylt 850d1bcdac9Sjeremylt @ref Advanced 851d1bcdac9Sjeremylt **/ 852d1bcdac9Sjeremylt 853d1bcdac9Sjeremylt int CeedOperatorFieldGetVector(CeedOperatorField opfield, 854d1bcdac9Sjeremylt CeedVector *vec) { 855fe2413ffSjeremylt *vec = opfield->vec; 856d1bcdac9Sjeremylt return 0; 857d1bcdac9Sjeremylt } 858d1bcdac9Sjeremylt 859d1bcdac9Sjeremylt /** 860b11c1e72Sjeremylt @brief Destroy a CeedOperator 861d7b241e6Sjeremylt 862d7b241e6Sjeremylt @param op CeedOperator to destroy 863b11c1e72Sjeremylt 864b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 865dfdf5a53Sjeremylt 866dfdf5a53Sjeremylt @ref Basic 867b11c1e72Sjeremylt **/ 868d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 869d7b241e6Sjeremylt int ierr; 870d7b241e6Sjeremylt 871d7b241e6Sjeremylt if (!*op || --(*op)->refcount > 0) return 0; 872d7b241e6Sjeremylt if ((*op)->Destroy) { 873d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 874d7b241e6Sjeremylt } 875fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 876fe2413ffSjeremylt // Free fields 8771d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 87852d6035fSJeremy L Thompson if ((*op)->inputfields[i]) { 87971352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->inputfields[i]->Erestrict); 88071352a93Sjeremylt CeedChk(ierr); 88171352a93Sjeremylt if ((*op)->inputfields[i]->basis != CEED_BASIS_COLLOCATED) { 88271352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->inputfields[i]->basis); CeedChk(ierr); 88371352a93Sjeremylt } 88471352a93Sjeremylt if ((*op)->inputfields[i]->vec != CEED_VECTOR_ACTIVE && 88571352a93Sjeremylt (*op)->inputfields[i]->vec != CEED_VECTOR_NONE ) { 88671352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->inputfields[i]->vec); CeedChk(ierr); 88771352a93Sjeremylt } 888fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields[i]); CeedChk(ierr); 889fe2413ffSjeremylt } 8901d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 891d0eb30a5Sjeremylt if ((*op)->outputfields[i]) { 89271352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->outputfields[i]->Erestrict); 89371352a93Sjeremylt CeedChk(ierr); 89471352a93Sjeremylt if ((*op)->outputfields[i]->basis != CEED_BASIS_COLLOCATED) { 89571352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->outputfields[i]->basis); CeedChk(ierr); 89671352a93Sjeremylt } 89771352a93Sjeremylt if ((*op)->outputfields[i]->vec != CEED_VECTOR_ACTIVE && 89871352a93Sjeremylt (*op)->outputfields[i]->vec != CEED_VECTOR_NONE ) { 89971352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->outputfields[i]->vec); CeedChk(ierr); 90071352a93Sjeremylt } 901fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields[i]); CeedChk(ierr); 902fe2413ffSjeremylt } 90352d6035fSJeremy L Thompson // Destroy suboperators 9041d102b48SJeremy L Thompson for (int i=0; i<(*op)->numsub; i++) 90552d6035fSJeremy L Thompson if ((*op)->suboperators[i]) { 90652d6035fSJeremy L Thompson ierr = CeedOperatorDestroy(&(*op)->suboperators[i]); CeedChk(ierr); 90752d6035fSJeremy L Thompson } 908d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 909d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 910d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 911fe2413ffSjeremylt 912fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields); CeedChk(ierr); 913fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields); CeedChk(ierr); 91452d6035fSJeremy L Thompson ierr = CeedFree(&(*op)->suboperators); CeedChk(ierr); 915d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 916d7b241e6Sjeremylt return 0; 917d7b241e6Sjeremylt } 918d7b241e6Sjeremylt 919d7b241e6Sjeremylt /// @} 920