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); 171d7b241e6Sjeremylt if (op->numelements && 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; 178d7b241e6Sjeremylt 179783c99b3SValeria Barra if (b != CEED_BASIS_COLLOCATED) { 180d7b241e6Sjeremylt CeedInt numqpoints; 181d7b241e6Sjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &numqpoints); CeedChk(ierr); 182d7b241e6Sjeremylt if (op->numqpoints && op->numqpoints != numqpoints) 183c042f62fSJeremy L Thompson // LCOV_EXCL_START 1841d102b48SJeremy L Thompson return CeedError(op->ceed, 1, "Basis with %d quadrature points " 1851d102b48SJeremy L Thompson "incompatible with prior %d points", numqpoints, 1861d102b48SJeremy L Thompson op->numqpoints); 187c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 188d7b241e6Sjeremylt op->numqpoints = numqpoints; 189d7b241e6Sjeremylt } 190d1bcdac9Sjeremylt CeedOperatorField *ofield; 191d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numinputfields; i++) { 192fe2413ffSjeremylt if (!strcmp(fieldname, (*op->qf->inputfields[i]).fieldname)) { 193d7b241e6Sjeremylt ofield = &op->inputfields[i]; 194d7b241e6Sjeremylt goto found; 195d7b241e6Sjeremylt } 196d7b241e6Sjeremylt } 197d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numoutputfields; i++) { 198fe2413ffSjeremylt if (!strcmp(fieldname, (*op->qf->outputfields[i]).fieldname)) { 199d7b241e6Sjeremylt ofield = &op->outputfields[i]; 200d7b241e6Sjeremylt goto found; 201d7b241e6Sjeremylt } 202d7b241e6Sjeremylt } 203c042f62fSJeremy L Thompson // LCOV_EXCL_START 204d7b241e6Sjeremylt return CeedError(op->ceed, 1, "QFunction has no knowledge of field '%s'", 205d7b241e6Sjeremylt fieldname); 206c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 207d7b241e6Sjeremylt found: 208fe2413ffSjeremylt ierr = CeedCalloc(1, ofield); CeedChk(ierr); 209fe2413ffSjeremylt (*ofield)->Erestrict = r; 21071352a93Sjeremylt r->refcount += 1; 211fe2413ffSjeremylt (*ofield)->lmode = lmode; 212fe2413ffSjeremylt (*ofield)->basis = b; 21371352a93Sjeremylt if (b != CEED_BASIS_COLLOCATED) 21471352a93Sjeremylt b->refcount += 1; 215fe2413ffSjeremylt (*ofield)->vec = v; 21671352a93Sjeremylt if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE) 21771352a93Sjeremylt v->refcount += 1; 218d7b241e6Sjeremylt op->nfields += 1; 219d7b241e6Sjeremylt return 0; 220d7b241e6Sjeremylt } 221d7b241e6Sjeremylt 222d7b241e6Sjeremylt /** 22352d6035fSJeremy L Thompson @brief Add a sub-operator to a composite CeedOperator 224288c0443SJeremy L Thompson 225288c0443SJeremy L Thompson @param[out] compositeop Address of the composite CeedOperator 226288c0443SJeremy L Thompson @param subop Address of the sub-operator CeedOperator 22752d6035fSJeremy L Thompson 22852d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 22952d6035fSJeremy L Thompson 23052d6035fSJeremy L Thompson @ref Basic 23152d6035fSJeremy L Thompson */ 23252d6035fSJeremy L Thompson int CeedCompositeOperatorAddSub(CeedOperator compositeop, 23352d6035fSJeremy L Thompson CeedOperator subop) { 23452d6035fSJeremy L Thompson if (!compositeop->composite) 235c042f62fSJeremy L Thompson // LCOV_EXCL_START 2361d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "CeedOperator is not a composite " 2371d102b48SJeremy L Thompson "operator"); 238c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 23952d6035fSJeremy L Thompson 24052d6035fSJeremy L Thompson if (compositeop->numsub == CEED_COMPOSITE_MAX) 241c042f62fSJeremy L Thompson // LCOV_EXCL_START 2421d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "Cannot add additional suboperators"); 243c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 24452d6035fSJeremy L Thompson 24552d6035fSJeremy L Thompson compositeop->suboperators[compositeop->numsub] = subop; 24652d6035fSJeremy L Thompson subop->refcount++; 24752d6035fSJeremy L Thompson compositeop->numsub++; 24852d6035fSJeremy L Thompson return 0; 24952d6035fSJeremy L Thompson } 25052d6035fSJeremy L Thompson 25152d6035fSJeremy L Thompson /** 2521d102b48SJeremy L Thompson @brief Assemble a linear CeedQFunction associated with a CeedOperator 2531d102b48SJeremy L Thompson 2541d102b48SJeremy L Thompson This returns a CeedVector containing a matrix at each quadrature point 2551d102b48SJeremy L Thompson providing the action of the CeedQFunction associated with the CeedOperator. 2561d102b48SJeremy L Thompson The vector 'assembled' is of shape 2571d102b48SJeremy L Thompson [num_elements, num_input_fields, num_output_fields, num_quad_points] 2581d102b48SJeremy L Thompson and contains column-major matrices representing the action of the 2591d102b48SJeremy L Thompson CeedQFunction for a corresponding quadrature point on an element. Inputs and 2601d102b48SJeremy L Thompson outputs are in the order provided by the user when adding CeedOperator fields. 2611d102b48SJeremy L Thompson For example, a QFunction with inputs 'u' and 'gradu' and outputs 'gradv' and 2621d102b48SJeremy L Thompson 'v', provided in that order, would result in an assembled QFunction that 2631d102b48SJeremy L Thompson consists of (1 + dim) x (dim + 1) matrices at each quadrature point acting 2641d102b48SJeremy L Thompson on the input [u, du_0, du_1] and producing the output [dv_0, dv_1, v]. 2651d102b48SJeremy L Thompson 2661d102b48SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 2671d102b48SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedQFunction at 2681d102b48SJeremy L Thompson quadrature points 2691d102b48SJeremy L Thompson @param[out] rstr CeedElemRestriction for CeedVector containing assembled 2701d102b48SJeremy L Thompson CeedQFunction 2711d102b48SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 2721d102b48SJeremy L Thompson CEED_REQUEST_IMMEDIATE 2731d102b48SJeremy L Thompson 2741d102b48SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2751d102b48SJeremy L Thompson 276*b7ec98d8SJeremy L Thompson @ref Basic 2771d102b48SJeremy L Thompson **/ 2781d102b48SJeremy L Thompson int CeedOperatorAssembleLinearQFunction(CeedOperator op, CeedVector *assembled, 2791d102b48SJeremy L Thompson CeedElemRestriction *rstr, CeedRequest *request) { 2801d102b48SJeremy L Thompson int ierr; 2811d102b48SJeremy L Thompson Ceed ceed = op->ceed; 2821d102b48SJeremy L Thompson CeedQFunction qf = op->qf; 2831d102b48SJeremy L Thompson 2841d102b48SJeremy L Thompson if (op->composite) { 285138d4072Sjeremylt // LCOV_EXCL_START 2861d102b48SJeremy L Thompson return CeedError(ceed, 1, "Cannot assemble QFunction for composite operator"); 287138d4072Sjeremylt // LCOV_EXCL_STOP 2881d102b48SJeremy L Thompson } else { 2891d102b48SJeremy L Thompson if (op->nfields == 0) 290138d4072Sjeremylt // LCOV_EXCL_START 2911d102b48SJeremy L Thompson return CeedError(ceed, 1, "No operator fields set"); 292138d4072Sjeremylt // LCOV_EXCL_STOP 2931d102b48SJeremy L Thompson if (op->nfields < qf->numinputfields + qf->numoutputfields) 294138d4072Sjeremylt // LCOV_EXCL_START 2951d102b48SJeremy L Thompson return CeedError( ceed, 1, "Not all operator fields set"); 296138d4072Sjeremylt // LCOV_EXCL_STOP 2971d102b48SJeremy L Thompson if (op->numelements == 0) 298138d4072Sjeremylt // LCOV_EXCL_START 2991d102b48SJeremy L Thompson return CeedError(ceed, 1, "At least one restriction required"); 300138d4072Sjeremylt // LCOV_EXCL_STOP 3011d102b48SJeremy L Thompson if (op->numqpoints == 0) 302138d4072Sjeremylt // LCOV_EXCL_START 3031d102b48SJeremy L Thompson return CeedError(ceed, 1, "At least one non-collocated basis required"); 304138d4072Sjeremylt // LCOV_EXCL_STOP 3051d102b48SJeremy L Thompson } 3061d102b48SJeremy L Thompson ierr = op->AssembleLinearQFunction(op, assembled, rstr, request); 3071d102b48SJeremy L Thompson CeedChk(ierr); 3081d102b48SJeremy L Thompson return 0; 3091d102b48SJeremy L Thompson } 3101d102b48SJeremy L Thompson 3111d102b48SJeremy L Thompson /** 312*b7ec98d8SJeremy L Thompson @brief Assemble the diagonal of a square linear Operator 313*b7ec98d8SJeremy L Thompson 314*b7ec98d8SJeremy L Thompson This returns a CeedVector containing the diagonal of a linear CeedOperator. 315*b7ec98d8SJeremy L Thompson 316*b7ec98d8SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 317*b7ec98d8SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedOperator diagonal 318*b7ec98d8SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 319*b7ec98d8SJeremy L Thompson CEED_REQUEST_IMMEDIATE 320*b7ec98d8SJeremy L Thompson 321*b7ec98d8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 322*b7ec98d8SJeremy L Thompson 323*b7ec98d8SJeremy L Thompson @ref Basic 324*b7ec98d8SJeremy L Thompson **/ 325*b7ec98d8SJeremy L Thompson int CeedOperatorAssembleLinearDiagonal(CeedOperator op, 326*b7ec98d8SJeremy L Thompson CeedVector *assembled, CeedRequest *request) { 327*b7ec98d8SJeremy L Thompson int ierr; 328*b7ec98d8SJeremy L Thompson Ceed ceed = op->ceed; 329*b7ec98d8SJeremy L Thompson CeedQFunction qf = op->qf; 330*b7ec98d8SJeremy L Thompson 331*b7ec98d8SJeremy L Thompson if (op->composite) { 332*b7ec98d8SJeremy L Thompson // LCOV_EXCL_START 333*b7ec98d8SJeremy L Thompson return CeedError(ceed, 1, "Cannot assemble QFunction for composite operator"); 334*b7ec98d8SJeremy L Thompson // LCOV_EXCL_STOP 335*b7ec98d8SJeremy L Thompson } else { 336*b7ec98d8SJeremy L Thompson if (op->nfields == 0) 337*b7ec98d8SJeremy L Thompson // LCOV_EXCL_START 338*b7ec98d8SJeremy L Thompson return CeedError(ceed, 1, "No operator fields set"); 339*b7ec98d8SJeremy L Thompson // LCOV_EXCL_STOP 340*b7ec98d8SJeremy L Thompson if (op->nfields < qf->numinputfields + qf->numoutputfields) 341*b7ec98d8SJeremy L Thompson // LCOV_EXCL_START 342*b7ec98d8SJeremy L Thompson return CeedError( ceed, 1, "Not all operator fields set"); 343*b7ec98d8SJeremy L Thompson // LCOV_EXCL_STOP 344*b7ec98d8SJeremy L Thompson if (op->numelements == 0) 345*b7ec98d8SJeremy L Thompson // LCOV_EXCL_START 346*b7ec98d8SJeremy L Thompson return CeedError(ceed, 1, "At least one restriction required"); 347*b7ec98d8SJeremy L Thompson // LCOV_EXCL_STOP 348*b7ec98d8SJeremy L Thompson if (op->numqpoints == 0) 349*b7ec98d8SJeremy L Thompson // LCOV_EXCL_START 350*b7ec98d8SJeremy L Thompson return CeedError(ceed, 1, "At least one non-collocated basis required"); 351*b7ec98d8SJeremy L Thompson // LCOV_EXCL_STOP 352*b7ec98d8SJeremy L Thompson } 353*b7ec98d8SJeremy L Thompson 354*b7ec98d8SJeremy L Thompson // Use backend version, if available 355*b7ec98d8SJeremy L Thompson if (op->AssembleLinearDiagonal) { 356*b7ec98d8SJeremy L Thompson ierr = op->AssembleLinearDiagonal(op, assembled, request); CeedChk(ierr); 357*b7ec98d8SJeremy L Thompson return 0; 358*b7ec98d8SJeremy L Thompson } 359*b7ec98d8SJeremy L Thompson 360*b7ec98d8SJeremy L Thompson // Assemble QFunction 361*b7ec98d8SJeremy L Thompson CeedVector assembledqf; 362*b7ec98d8SJeremy L Thompson CeedElemRestriction rstr; 363*b7ec98d8SJeremy L Thompson ierr = CeedOperatorAssembleLinearQFunction(op, &assembledqf, &rstr, request); 364*b7ec98d8SJeremy L Thompson CeedChk(ierr); 365*b7ec98d8SJeremy L Thompson ierr = CeedElemRestrictionDestroy(&rstr); CeedChk(ierr); 366*b7ec98d8SJeremy L Thompson 367*b7ec98d8SJeremy L Thompson // Determine active input basis 368*b7ec98d8SJeremy L Thompson CeedInt numemodein = 0, ncomp, dim; 369*b7ec98d8SJeremy L Thompson CeedEvalMode *emodein = NULL; 370*b7ec98d8SJeremy L Thompson CeedBasis basisin; 371*b7ec98d8SJeremy L Thompson CeedElemRestriction rstrin; 372*b7ec98d8SJeremy L Thompson for (CeedInt i=0; i<qf->numinputfields; i++) 373*b7ec98d8SJeremy L Thompson if (op->inputfields[i]->vec == CEED_VECTOR_ACTIVE) { 374*b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetBasis(op->inputfields[i], &basisin); 375*b7ec98d8SJeremy L Thompson CeedChk(ierr); 376*b7ec98d8SJeremy L Thompson ierr = CeedBasisGetNumComponents(basisin, &ncomp); CeedChk(ierr); 377*b7ec98d8SJeremy L Thompson ierr = CeedBasisGetDimension(basisin, &dim); CeedChk(ierr); 378*b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetElemRestriction(op->inputfields[i], &rstrin); 379*b7ec98d8SJeremy L Thompson CeedChk(ierr); 380*b7ec98d8SJeremy L Thompson CeedEvalMode emode; 381*b7ec98d8SJeremy L Thompson ierr = CeedQFunctionFieldGetEvalMode(qf->inputfields[i], &emode); 382*b7ec98d8SJeremy L Thompson CeedChk(ierr); 383*b7ec98d8SJeremy L Thompson switch (emode) { 384*b7ec98d8SJeremy L Thompson case CEED_EVAL_NONE: 385*b7ec98d8SJeremy L Thompson case CEED_EVAL_INTERP: 386*b7ec98d8SJeremy L Thompson ierr = CeedRealloc(numemodein + 1, &emodein); CeedChk(ierr); 387*b7ec98d8SJeremy L Thompson emodein[numemodein] = emode; 388*b7ec98d8SJeremy L Thompson numemodein += 1; 389*b7ec98d8SJeremy L Thompson break; 390*b7ec98d8SJeremy L Thompson case CEED_EVAL_GRAD: 391*b7ec98d8SJeremy L Thompson ierr = CeedRealloc(numemodein + dim, &emodein); CeedChk(ierr); 392*b7ec98d8SJeremy L Thompson for (CeedInt d=0; d<dim; d++) 393*b7ec98d8SJeremy L Thompson emodein[numemodein+d] = emode; 394*b7ec98d8SJeremy L Thompson numemodein += dim; 395*b7ec98d8SJeremy L Thompson break; 396*b7ec98d8SJeremy L Thompson case CEED_EVAL_WEIGHT: 397*b7ec98d8SJeremy L Thompson case CEED_EVAL_DIV: 398*b7ec98d8SJeremy L Thompson case CEED_EVAL_CURL: 399*b7ec98d8SJeremy L Thompson break; // Caught by QF Assembly 400*b7ec98d8SJeremy L Thompson } 401*b7ec98d8SJeremy L Thompson } 402*b7ec98d8SJeremy L Thompson 403*b7ec98d8SJeremy L Thompson // Determine active output basis 404*b7ec98d8SJeremy L Thompson CeedInt numemodeout = 0; 405*b7ec98d8SJeremy L Thompson CeedEvalMode *emodeout = NULL; 406*b7ec98d8SJeremy L Thompson CeedBasis basisout; 407*b7ec98d8SJeremy L Thompson CeedElemRestriction rstrout; 408*b7ec98d8SJeremy L Thompson CeedTransposeMode lmodeout; 409*b7ec98d8SJeremy L Thompson for (CeedInt i=0; i<qf->numoutputfields; i++) 410*b7ec98d8SJeremy L Thompson if (op->outputfields[i]->vec == CEED_VECTOR_ACTIVE) { 411*b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetBasis(op->outputfields[i], &basisout); 412*b7ec98d8SJeremy L Thompson CeedChk(ierr); 413*b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetElemRestriction(op->outputfields[i], &rstrout); 414*b7ec98d8SJeremy L Thompson CeedChk(ierr); 415*b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetLMode(op->outputfields[i], &lmodeout); 416*b7ec98d8SJeremy L Thompson CeedChk(ierr); 417*b7ec98d8SJeremy L Thompson CeedEvalMode emode; 418*b7ec98d8SJeremy L Thompson ierr = CeedQFunctionFieldGetEvalMode(qf->outputfields[i], &emode); 419*b7ec98d8SJeremy L Thompson CeedChk(ierr); 420*b7ec98d8SJeremy L Thompson switch (emode) { 421*b7ec98d8SJeremy L Thompson case CEED_EVAL_NONE: 422*b7ec98d8SJeremy L Thompson case CEED_EVAL_INTERP: 423*b7ec98d8SJeremy L Thompson ierr = CeedRealloc(numemodeout + 1, &emodeout); CeedChk(ierr); 424*b7ec98d8SJeremy L Thompson emodeout[numemodeout] = emode; 425*b7ec98d8SJeremy L Thompson numemodeout += 1; 426*b7ec98d8SJeremy L Thompson break; 427*b7ec98d8SJeremy L Thompson case CEED_EVAL_GRAD: 428*b7ec98d8SJeremy L Thompson ierr = CeedRealloc(numemodeout + dim, &emodeout); CeedChk(ierr); 429*b7ec98d8SJeremy L Thompson for (CeedInt d=0; d<dim; d++) 430*b7ec98d8SJeremy L Thompson emodeout[numemodeout+d] = emode; 431*b7ec98d8SJeremy L Thompson numemodeout += dim; 432*b7ec98d8SJeremy L Thompson break; 433*b7ec98d8SJeremy L Thompson case CEED_EVAL_WEIGHT: 434*b7ec98d8SJeremy L Thompson case CEED_EVAL_DIV: 435*b7ec98d8SJeremy L Thompson case CEED_EVAL_CURL: 436*b7ec98d8SJeremy L Thompson break; // Caught by QF Assembly 437*b7ec98d8SJeremy L Thompson } 438*b7ec98d8SJeremy L Thompson } 439*b7ec98d8SJeremy L Thompson 440*b7ec98d8SJeremy L Thompson // Create diagonal vector 441*b7ec98d8SJeremy L Thompson CeedVector elemdiag; 442*b7ec98d8SJeremy L Thompson ierr = CeedElemRestrictionCreateVector(rstrin, assembled, &elemdiag); 443*b7ec98d8SJeremy L Thompson CeedChk(ierr); 444*b7ec98d8SJeremy L Thompson 445*b7ec98d8SJeremy L Thompson // Assemble element operator diagonals 446*b7ec98d8SJeremy L Thompson CeedScalar *elemdiagarray, *assembledqfarray; 447*b7ec98d8SJeremy L Thompson ierr = CeedVectorSetValue(elemdiag, 0.0); CeedChk(ierr); 448*b7ec98d8SJeremy L Thompson ierr = CeedVectorGetArray(elemdiag, CEED_MEM_HOST, &elemdiagarray); 449*b7ec98d8SJeremy L Thompson CeedChk(ierr); 450*b7ec98d8SJeremy L Thompson ierr = CeedVectorGetArray(assembledqf, CEED_MEM_HOST, &assembledqfarray); 451*b7ec98d8SJeremy L Thompson CeedChk(ierr); 452*b7ec98d8SJeremy L Thompson CeedInt nelem, nnodes, nqpts; 453*b7ec98d8SJeremy L Thompson ierr = CeedElemRestrictionGetNumElements(rstrin, &nelem); CeedChk(ierr); 454*b7ec98d8SJeremy L Thompson ierr = CeedBasisGetNumNodes(basisin, &nnodes); CeedChk(ierr); 455*b7ec98d8SJeremy L Thompson ierr = CeedBasisGetNumQuadraturePoints(basisin, &nqpts); CeedChk(ierr); 456*b7ec98d8SJeremy L Thompson // Compute the diagonal of B^T D B 457*b7ec98d8SJeremy L Thompson // Each node, qpt pair 458*b7ec98d8SJeremy L Thompson for (CeedInt n=0; n<nnodes; n++) 459*b7ec98d8SJeremy L Thompson for (CeedInt q=0; q<nqpts; q++) { 460*b7ec98d8SJeremy L Thompson CeedInt dout = -1; 461*b7ec98d8SJeremy L Thompson // Each basis eval mode pair 462*b7ec98d8SJeremy L Thompson for (CeedInt eout=0; eout<numemodeout; eout++) { 463*b7ec98d8SJeremy L Thompson CeedScalar bt = 1.0; 464*b7ec98d8SJeremy L Thompson if (emodeout[eout] == CEED_EVAL_GRAD) 465*b7ec98d8SJeremy L Thompson dout += 1; 466*b7ec98d8SJeremy L Thompson ierr = CeedBasisGetValue(basisout, emodeout[eout], q, n, dout, &bt); 467*b7ec98d8SJeremy L Thompson CeedChk(ierr); 468*b7ec98d8SJeremy L Thompson CeedInt din = -1; 469*b7ec98d8SJeremy L Thompson for (CeedInt ein=0; ein<numemodein; ein++) { 470*b7ec98d8SJeremy L Thompson CeedScalar b = 0.0; 471*b7ec98d8SJeremy L Thompson if (emodein[ein] == CEED_EVAL_GRAD) 472*b7ec98d8SJeremy L Thompson din += 1; 473*b7ec98d8SJeremy L Thompson ierr = CeedBasisGetValue(basisin, emodein[ein], q, n, din, &b); 474*b7ec98d8SJeremy L Thompson CeedChk(ierr); 475*b7ec98d8SJeremy L Thompson // Each element and component 476*b7ec98d8SJeremy L Thompson for (CeedInt e=0; e<nelem; e++) 477*b7ec98d8SJeremy L Thompson for (CeedInt cout=0; cout<ncomp; cout++) { 478*b7ec98d8SJeremy L Thompson CeedScalar db = 0.0; 479*b7ec98d8SJeremy L Thompson for (CeedInt cin=0; cin<ncomp; cin++) 480*b7ec98d8SJeremy L Thompson db += assembledqfarray[((((e*numemodein+ein)*ncomp+cin)* 481*b7ec98d8SJeremy L Thompson numemodeout+eout)*ncomp+cout)*nqpts+q]*b; 482*b7ec98d8SJeremy L Thompson elemdiagarray[(e*ncomp+cout)*nnodes+n] += bt * db; 483*b7ec98d8SJeremy L Thompson } 484*b7ec98d8SJeremy L Thompson } 485*b7ec98d8SJeremy L Thompson } 486*b7ec98d8SJeremy L Thompson } 487*b7ec98d8SJeremy L Thompson 488*b7ec98d8SJeremy L Thompson ierr = CeedVectorRestoreArray(elemdiag, &elemdiagarray); CeedChk(ierr); 489*b7ec98d8SJeremy L Thompson ierr = CeedVectorRestoreArray(assembledqf, &assembledqfarray); CeedChk(ierr); 490*b7ec98d8SJeremy L Thompson 491*b7ec98d8SJeremy L Thompson // Assemble local operator diagonal 492*b7ec98d8SJeremy L Thompson ierr = CeedVectorSetValue(*assembled, 0.0); CeedChk(ierr); 493*b7ec98d8SJeremy L Thompson ierr = CeedElemRestrictionApply(rstrout, CEED_TRANSPOSE, lmodeout, elemdiag, 494*b7ec98d8SJeremy L Thompson *assembled, request); CeedChk(ierr); 495*b7ec98d8SJeremy L Thompson 496*b7ec98d8SJeremy L Thompson // Cleanup 497*b7ec98d8SJeremy L Thompson ierr = CeedVectorDestroy(&assembledqf); CeedChk(ierr); 498*b7ec98d8SJeremy L Thompson ierr = CeedVectorDestroy(&elemdiag); CeedChk(ierr); 499*b7ec98d8SJeremy L Thompson ierr = CeedFree(&emodein); CeedChk(ierr); 500*b7ec98d8SJeremy L Thompson ierr = CeedFree(&emodeout); CeedChk(ierr); 501*b7ec98d8SJeremy L Thompson 502*b7ec98d8SJeremy L Thompson return 0; 503*b7ec98d8SJeremy L Thompson } 504*b7ec98d8SJeremy L Thompson 505*b7ec98d8SJeremy L Thompson /** 506b11c1e72Sjeremylt @brief Apply CeedOperator to a vector 507d7b241e6Sjeremylt 508d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 509d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 510d7b241e6Sjeremylt CeedOperatorSetField(). 511d7b241e6Sjeremylt 512d7b241e6Sjeremylt @param op CeedOperator to apply 513b11c1e72Sjeremylt @param[in] in CeedVector containing input state or NULL if there are no 514b11c1e72Sjeremylt active inputs 515b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 516d7b241e6Sjeremylt distinct from @a in) or NULL if there are no active outputs 517d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 518d7b241e6Sjeremylt CEED_REQUEST_IMMEDIATE 519b11c1e72Sjeremylt 520b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 521dfdf5a53Sjeremylt 522dfdf5a53Sjeremylt @ref Basic 523b11c1e72Sjeremylt **/ 524d7b241e6Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, 525d7b241e6Sjeremylt CeedVector out, CeedRequest *request) { 526d7b241e6Sjeremylt int ierr; 527d7b241e6Sjeremylt Ceed ceed = op->ceed; 528d7b241e6Sjeremylt CeedQFunction qf = op->qf; 529d7b241e6Sjeremylt 53052d6035fSJeremy L Thompson if (op->composite) { 531c042f62fSJeremy L Thompson if (!op->numsub) 532c042f62fSJeremy L Thompson // LCOV_EXCL_START 533c042f62fSJeremy L Thompson return CeedError(ceed, 1, "No suboperators set"); 534c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 53552d6035fSJeremy L Thompson } else { 536c042f62fSJeremy L Thompson if (op->nfields == 0) 537c042f62fSJeremy L Thompson // LCOV_EXCL_START 538c042f62fSJeremy L Thompson return CeedError(ceed, 1, "No operator fields set"); 539c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 540c042f62fSJeremy L Thompson if (op->nfields < qf->numinputfields + qf->numoutputfields) 541c042f62fSJeremy L Thompson // LCOV_EXCL_START 542c042f62fSJeremy L Thompson return CeedError(ceed, 1, "Not all operator fields set"); 543c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 544c042f62fSJeremy L Thompson if (op->numelements == 0) 545c042f62fSJeremy L Thompson // LCOV_EXCL_START 546c042f62fSJeremy L Thompson return CeedError(ceed, 1,"At least one restriction required"); 547c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 548c042f62fSJeremy L Thompson if (op->numqpoints == 0) 549c042f62fSJeremy L Thompson // LCOV_EXCL_START 550c042f62fSJeremy L Thompson return CeedError(ceed, 1,"At least one non-collocated basis required"); 551c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 55252d6035fSJeremy L Thompson } 553d7b241e6Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 554d7b241e6Sjeremylt return 0; 555d7b241e6Sjeremylt } 556d7b241e6Sjeremylt 557d7b241e6Sjeremylt /** 5584ce2993fSjeremylt @brief Get the Ceed associated with a CeedOperator 5594ce2993fSjeremylt 5604ce2993fSjeremylt @param op CeedOperator 5614ce2993fSjeremylt @param[out] ceed Variable to store Ceed 5624ce2993fSjeremylt 5634ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5644ce2993fSjeremylt 56523617272Sjeremylt @ref Advanced 5664ce2993fSjeremylt **/ 5674ce2993fSjeremylt 5684ce2993fSjeremylt int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 5694ce2993fSjeremylt *ceed = op->ceed; 5704ce2993fSjeremylt return 0; 5714ce2993fSjeremylt } 5724ce2993fSjeremylt 5734ce2993fSjeremylt /** 5744ce2993fSjeremylt @brief Get the number of elements associated with a CeedOperator 5754ce2993fSjeremylt 5764ce2993fSjeremylt @param op CeedOperator 5774ce2993fSjeremylt @param[out] numelem Variable to store number of elements 5784ce2993fSjeremylt 5794ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5804ce2993fSjeremylt 58123617272Sjeremylt @ref Advanced 5824ce2993fSjeremylt **/ 5834ce2993fSjeremylt 5844ce2993fSjeremylt int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) { 58552d6035fSJeremy L Thompson if (op->composite) 586c042f62fSJeremy L Thompson // LCOV_EXCL_START 58752d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 588c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 58952d6035fSJeremy L Thompson 5904ce2993fSjeremylt *numelem = op->numelements; 5914ce2993fSjeremylt return 0; 5924ce2993fSjeremylt } 5934ce2993fSjeremylt 5944ce2993fSjeremylt /** 5954ce2993fSjeremylt @brief Get the number of quadrature points associated with a CeedOperator 5964ce2993fSjeremylt 5974ce2993fSjeremylt @param op CeedOperator 5984ce2993fSjeremylt @param[out] numqpts Variable to store vector number of quadrature points 5994ce2993fSjeremylt 6004ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6014ce2993fSjeremylt 60223617272Sjeremylt @ref Advanced 6034ce2993fSjeremylt **/ 6044ce2993fSjeremylt 6054ce2993fSjeremylt int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) { 60652d6035fSJeremy L Thompson if (op->composite) 607c042f62fSJeremy L Thompson // LCOV_EXCL_START 60852d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 609c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 61052d6035fSJeremy L Thompson 6114ce2993fSjeremylt *numqpts = op->numqpoints; 6124ce2993fSjeremylt return 0; 6134ce2993fSjeremylt } 6144ce2993fSjeremylt 6154ce2993fSjeremylt /** 6164ce2993fSjeremylt @brief Get the number of arguments associated with a CeedOperator 6174ce2993fSjeremylt 6184ce2993fSjeremylt @param op CeedOperator 6194ce2993fSjeremylt @param[out] numargs Variable to store vector number of arguments 6204ce2993fSjeremylt 6214ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6224ce2993fSjeremylt 62323617272Sjeremylt @ref Advanced 6244ce2993fSjeremylt **/ 6254ce2993fSjeremylt 6264ce2993fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) { 62752d6035fSJeremy L Thompson if (op->composite) 628c042f62fSJeremy L Thompson // LCOV_EXCL_START 62952d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operators"); 630c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 631c042f62fSJeremy L Thompson 6324ce2993fSjeremylt *numargs = op->nfields; 6334ce2993fSjeremylt return 0; 6344ce2993fSjeremylt } 6354ce2993fSjeremylt 6364ce2993fSjeremylt /** 6374ce2993fSjeremylt @brief Get the setup status of a CeedOperator 6384ce2993fSjeremylt 6394ce2993fSjeremylt @param op CeedOperator 640288c0443SJeremy L Thompson @param[out] setupdone Variable to store setup status 6414ce2993fSjeremylt 6424ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6434ce2993fSjeremylt 64423617272Sjeremylt @ref Advanced 6454ce2993fSjeremylt **/ 6464ce2993fSjeremylt 6474ce2993fSjeremylt int CeedOperatorGetSetupStatus(CeedOperator op, bool *setupdone) { 6484ce2993fSjeremylt *setupdone = op->setupdone; 6494ce2993fSjeremylt return 0; 6504ce2993fSjeremylt } 6514ce2993fSjeremylt 6524ce2993fSjeremylt /** 6534ce2993fSjeremylt @brief Get the QFunction associated with a CeedOperator 6544ce2993fSjeremylt 6554ce2993fSjeremylt @param op CeedOperator 6568c91a0c9SJeremy L Thompson @param[out] qf Variable to store QFunction 6574ce2993fSjeremylt 6584ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6594ce2993fSjeremylt 66023617272Sjeremylt @ref Advanced 6614ce2993fSjeremylt **/ 6624ce2993fSjeremylt 6634ce2993fSjeremylt int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 66452d6035fSJeremy L Thompson if (op->composite) 665c042f62fSJeremy L Thompson // LCOV_EXCL_START 66652d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 667c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 66852d6035fSJeremy L Thompson 6694ce2993fSjeremylt *qf = op->qf; 6704ce2993fSjeremylt return 0; 6714ce2993fSjeremylt } 6724ce2993fSjeremylt 6734ce2993fSjeremylt /** 67452d6035fSJeremy L Thompson @brief Get the number of suboperators associated with a CeedOperator 67552d6035fSJeremy L Thompson 67652d6035fSJeremy L Thompson @param op CeedOperator 67752d6035fSJeremy L Thompson @param[out] numsub Variable to store number of suboperators 67852d6035fSJeremy L Thompson 67952d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 68052d6035fSJeremy L Thompson 68152d6035fSJeremy L Thompson @ref Advanced 68252d6035fSJeremy L Thompson **/ 68352d6035fSJeremy L Thompson 68452d6035fSJeremy L Thompson int CeedOperatorGetNumSub(CeedOperator op, CeedInt *numsub) { 685c042f62fSJeremy L Thompson if (!op->composite) 686c042f62fSJeremy L Thompson // LCOV_EXCL_START 687c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 688c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 68952d6035fSJeremy L Thompson 69052d6035fSJeremy L Thompson *numsub = op->numsub; 69152d6035fSJeremy L Thompson return 0; 69252d6035fSJeremy L Thompson } 69352d6035fSJeremy L Thompson 69452d6035fSJeremy L Thompson /** 69552d6035fSJeremy L Thompson @brief Get the list of suboperators associated with a CeedOperator 69652d6035fSJeremy L Thompson 69752d6035fSJeremy L Thompson @param op CeedOperator 69852d6035fSJeremy L Thompson @param[out] suboperators Variable to store list of suboperators 69952d6035fSJeremy L Thompson 70052d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 70152d6035fSJeremy L Thompson 70252d6035fSJeremy L Thompson @ref Advanced 70352d6035fSJeremy L Thompson **/ 70452d6035fSJeremy L Thompson 70552d6035fSJeremy L Thompson int CeedOperatorGetSubList(CeedOperator op, CeedOperator* *suboperators) { 706c042f62fSJeremy L Thompson if (!op->composite) 707c042f62fSJeremy L Thompson // LCOV_EXCL_START 708c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 709c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 71052d6035fSJeremy L Thompson 71152d6035fSJeremy L Thompson *suboperators = op->suboperators; 71252d6035fSJeremy L Thompson return 0; 71352d6035fSJeremy L Thompson } 71452d6035fSJeremy L Thompson 71552d6035fSJeremy L Thompson /** 716fe2413ffSjeremylt @brief Set the backend data of a CeedOperator 717fe2413ffSjeremylt 718fe2413ffSjeremylt @param[out] op CeedOperator 719fe2413ffSjeremylt @param data Data to set 720fe2413ffSjeremylt 721fe2413ffSjeremylt @return An error code: 0 - success, otherwise - failure 722fe2413ffSjeremylt 723fe2413ffSjeremylt @ref Advanced 724fe2413ffSjeremylt **/ 725fe2413ffSjeremylt 726fe2413ffSjeremylt int CeedOperatorSetData(CeedOperator op, void* *data) { 727fe2413ffSjeremylt op->data = *data; 728fe2413ffSjeremylt return 0; 729fe2413ffSjeremylt } 730fe2413ffSjeremylt 731fe2413ffSjeremylt /** 7324ce2993fSjeremylt @brief Get the backend data of a CeedOperator 7334ce2993fSjeremylt 7344ce2993fSjeremylt @param op CeedOperator 7354ce2993fSjeremylt @param[out] data Variable to store data 7364ce2993fSjeremylt 7374ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7384ce2993fSjeremylt 73923617272Sjeremylt @ref Advanced 7404ce2993fSjeremylt **/ 7414ce2993fSjeremylt 7424ce2993fSjeremylt int CeedOperatorGetData(CeedOperator op, void* *data) { 7434ce2993fSjeremylt *data = op->data; 7444ce2993fSjeremylt return 0; 7454ce2993fSjeremylt } 7464ce2993fSjeremylt 7474ce2993fSjeremylt /** 7484ce2993fSjeremylt @brief Set the setup flag of a CeedOperator to True 7494ce2993fSjeremylt 7504ce2993fSjeremylt @param op CeedOperator 7514ce2993fSjeremylt 7524ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7534ce2993fSjeremylt 75423617272Sjeremylt @ref Advanced 7554ce2993fSjeremylt **/ 7564ce2993fSjeremylt 7574ce2993fSjeremylt int CeedOperatorSetSetupDone(CeedOperator op) { 7584ce2993fSjeremylt op->setupdone = 1; 7594ce2993fSjeremylt return 0; 7604ce2993fSjeremylt } 7614ce2993fSjeremylt 7624ce2993fSjeremylt /** 763d1bcdac9Sjeremylt @brief Get the CeedOperatorFields of a CeedOperator 764d1bcdac9Sjeremylt 765d1bcdac9Sjeremylt @param op CeedOperator 766d1bcdac9Sjeremylt @param[out] inputfields Variable to store inputfields 767d1bcdac9Sjeremylt @param[out] outputfields Variable to store outputfields 768d1bcdac9Sjeremylt 769d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 770d1bcdac9Sjeremylt 771d1bcdac9Sjeremylt @ref Advanced 772d1bcdac9Sjeremylt **/ 773d1bcdac9Sjeremylt 774d1bcdac9Sjeremylt int CeedOperatorGetFields(CeedOperator op, 775d1bcdac9Sjeremylt CeedOperatorField* *inputfields, 776d1bcdac9Sjeremylt CeedOperatorField* *outputfields) { 77752d6035fSJeremy L Thompson if (op->composite) 778c042f62fSJeremy L Thompson // LCOV_EXCL_START 77952d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 780c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 78152d6035fSJeremy L Thompson 782d1bcdac9Sjeremylt if (inputfields) *inputfields = op->inputfields; 783d1bcdac9Sjeremylt if (outputfields) *outputfields = op->outputfields; 784d1bcdac9Sjeremylt return 0; 785d1bcdac9Sjeremylt } 786d1bcdac9Sjeremylt 787d1bcdac9Sjeremylt /** 7884dccadb6Sjeremylt @brief Get the L vector CeedTransposeMode of a CeedOperatorField 7894dccadb6Sjeremylt 7904dccadb6Sjeremylt @param opfield CeedOperatorField 7914dccadb6Sjeremylt @param[out] lmode Variable to store CeedTransposeMode 7924dccadb6Sjeremylt 7934dccadb6Sjeremylt @return An error code: 0 - success, otherwise - failure 7944dccadb6Sjeremylt 7954dccadb6Sjeremylt @ref Advanced 7964dccadb6Sjeremylt **/ 7974dccadb6Sjeremylt 7984dccadb6Sjeremylt int CeedOperatorFieldGetLMode(CeedOperatorField opfield, 7994dccadb6Sjeremylt CeedTransposeMode *lmode) { 800fe2413ffSjeremylt *lmode = opfield->lmode; 8014dccadb6Sjeremylt return 0; 8022b8e417aSjeremylt } 8032b8e417aSjeremylt 8042b8e417aSjeremylt /** 805d1bcdac9Sjeremylt @brief Get the CeedElemRestriction of a CeedOperatorField 806d1bcdac9Sjeremylt 807d1bcdac9Sjeremylt @param opfield CeedOperatorField 808d1bcdac9Sjeremylt @param[out] rstr Variable to store CeedElemRestriction 809d1bcdac9Sjeremylt 810d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 811d1bcdac9Sjeremylt 812d1bcdac9Sjeremylt @ref Advanced 813d1bcdac9Sjeremylt **/ 814d1bcdac9Sjeremylt 815d1bcdac9Sjeremylt int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield, 816d1bcdac9Sjeremylt CeedElemRestriction *rstr) { 817fe2413ffSjeremylt *rstr = opfield->Erestrict; 818d1bcdac9Sjeremylt return 0; 819d1bcdac9Sjeremylt } 820d1bcdac9Sjeremylt 821d1bcdac9Sjeremylt /** 822d1bcdac9Sjeremylt @brief Get the CeedBasis of a CeedOperatorField 823d1bcdac9Sjeremylt 824d1bcdac9Sjeremylt @param opfield CeedOperatorField 825d1bcdac9Sjeremylt @param[out] basis Variable to store CeedBasis 826d1bcdac9Sjeremylt 827d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 828d1bcdac9Sjeremylt 829d1bcdac9Sjeremylt @ref Advanced 830d1bcdac9Sjeremylt **/ 831d1bcdac9Sjeremylt 832d1bcdac9Sjeremylt int CeedOperatorFieldGetBasis(CeedOperatorField opfield, 833d1bcdac9Sjeremylt CeedBasis *basis) { 834fe2413ffSjeremylt *basis = opfield->basis; 835d1bcdac9Sjeremylt return 0; 836d1bcdac9Sjeremylt } 837d1bcdac9Sjeremylt 838d1bcdac9Sjeremylt /** 839d1bcdac9Sjeremylt @brief Get the CeedVector of a CeedOperatorField 840d1bcdac9Sjeremylt 841d1bcdac9Sjeremylt @param opfield CeedOperatorField 842d1bcdac9Sjeremylt @param[out] vec Variable to store CeedVector 843d1bcdac9Sjeremylt 844d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 845d1bcdac9Sjeremylt 846d1bcdac9Sjeremylt @ref Advanced 847d1bcdac9Sjeremylt **/ 848d1bcdac9Sjeremylt 849d1bcdac9Sjeremylt int CeedOperatorFieldGetVector(CeedOperatorField opfield, 850d1bcdac9Sjeremylt CeedVector *vec) { 851fe2413ffSjeremylt *vec = opfield->vec; 852d1bcdac9Sjeremylt return 0; 853d1bcdac9Sjeremylt } 854d1bcdac9Sjeremylt 855d1bcdac9Sjeremylt /** 856b11c1e72Sjeremylt @brief Destroy a CeedOperator 857d7b241e6Sjeremylt 858d7b241e6Sjeremylt @param op CeedOperator to destroy 859b11c1e72Sjeremylt 860b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 861dfdf5a53Sjeremylt 862dfdf5a53Sjeremylt @ref Basic 863b11c1e72Sjeremylt **/ 864d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 865d7b241e6Sjeremylt int ierr; 866d7b241e6Sjeremylt 867d7b241e6Sjeremylt if (!*op || --(*op)->refcount > 0) return 0; 868d7b241e6Sjeremylt if ((*op)->Destroy) { 869d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 870d7b241e6Sjeremylt } 871fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 872fe2413ffSjeremylt // Free fields 8731d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 87452d6035fSJeremy L Thompson if ((*op)->inputfields[i]) { 87571352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->inputfields[i]->Erestrict); 87671352a93Sjeremylt CeedChk(ierr); 87771352a93Sjeremylt if ((*op)->inputfields[i]->basis != CEED_BASIS_COLLOCATED) { 87871352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->inputfields[i]->basis); CeedChk(ierr); 87971352a93Sjeremylt } 88071352a93Sjeremylt if ((*op)->inputfields[i]->vec != CEED_VECTOR_ACTIVE && 88171352a93Sjeremylt (*op)->inputfields[i]->vec != CEED_VECTOR_NONE ) { 88271352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->inputfields[i]->vec); CeedChk(ierr); 88371352a93Sjeremylt } 884fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields[i]); CeedChk(ierr); 885fe2413ffSjeremylt } 8861d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 887d0eb30a5Sjeremylt if ((*op)->outputfields[i]) { 88871352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->outputfields[i]->Erestrict); 88971352a93Sjeremylt CeedChk(ierr); 89071352a93Sjeremylt if ((*op)->outputfields[i]->basis != CEED_BASIS_COLLOCATED) { 89171352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->outputfields[i]->basis); CeedChk(ierr); 89271352a93Sjeremylt } 89371352a93Sjeremylt if ((*op)->outputfields[i]->vec != CEED_VECTOR_ACTIVE && 89471352a93Sjeremylt (*op)->outputfields[i]->vec != CEED_VECTOR_NONE ) { 89571352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->outputfields[i]->vec); CeedChk(ierr); 89671352a93Sjeremylt } 897fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields[i]); CeedChk(ierr); 898fe2413ffSjeremylt } 89952d6035fSJeremy L Thompson // Destroy suboperators 9001d102b48SJeremy L Thompson for (int i=0; i<(*op)->numsub; i++) 90152d6035fSJeremy L Thompson if ((*op)->suboperators[i]) { 90252d6035fSJeremy L Thompson ierr = CeedOperatorDestroy(&(*op)->suboperators[i]); CeedChk(ierr); 90352d6035fSJeremy L Thompson } 904d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 905d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 906d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 907fe2413ffSjeremylt 908fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields); CeedChk(ierr); 909fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields); CeedChk(ierr); 91052d6035fSJeremy L Thompson ierr = CeedFree(&(*op)->suboperators); CeedChk(ierr); 911d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 912d7b241e6Sjeremylt return 0; 913d7b241e6Sjeremylt } 914d7b241e6Sjeremylt 915d7b241e6Sjeremylt /// @} 916