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 276b7ec98d8SJeremy L Thompson @ref Basic 2771d102b48SJeremy L Thompson **/ 2781d102b48SJeremy L Thompson int CeedOperatorAssembleLinearQFunction(CeedOperator op, CeedVector *assembled, 2797f823360Sjeremylt CeedElemRestriction *rstr, 2807f823360Sjeremylt CeedRequest *request) { 2811d102b48SJeremy L Thompson int ierr; 2821d102b48SJeremy L Thompson Ceed ceed = op->ceed; 2831d102b48SJeremy L Thompson CeedQFunction qf = op->qf; 2841d102b48SJeremy L Thompson 2851d102b48SJeremy L Thompson if (op->composite) { 286138d4072Sjeremylt // LCOV_EXCL_START 2871d102b48SJeremy L Thompson return CeedError(ceed, 1, "Cannot assemble QFunction for composite operator"); 288138d4072Sjeremylt // LCOV_EXCL_STOP 2891d102b48SJeremy L Thompson } else { 2901d102b48SJeremy L Thompson if (op->nfields == 0) 291138d4072Sjeremylt // LCOV_EXCL_START 2921d102b48SJeremy L Thompson return CeedError(ceed, 1, "No operator fields set"); 293138d4072Sjeremylt // LCOV_EXCL_STOP 2941d102b48SJeremy L Thompson if (op->nfields < qf->numinputfields + qf->numoutputfields) 295138d4072Sjeremylt // LCOV_EXCL_START 2961d102b48SJeremy L Thompson return CeedError( ceed, 1, "Not all operator fields set"); 297138d4072Sjeremylt // LCOV_EXCL_STOP 2981d102b48SJeremy L Thompson if (op->numelements == 0) 299138d4072Sjeremylt // LCOV_EXCL_START 3001d102b48SJeremy L Thompson return CeedError(ceed, 1, "At least one restriction required"); 301138d4072Sjeremylt // LCOV_EXCL_STOP 3021d102b48SJeremy L Thompson if (op->numqpoints == 0) 303138d4072Sjeremylt // LCOV_EXCL_START 3041d102b48SJeremy L Thompson return CeedError(ceed, 1, "At least one non-collocated basis required"); 305138d4072Sjeremylt // LCOV_EXCL_STOP 3061d102b48SJeremy L Thompson } 3071d102b48SJeremy L Thompson ierr = op->AssembleLinearQFunction(op, assembled, rstr, request); 3081d102b48SJeremy L Thompson CeedChk(ierr); 3091d102b48SJeremy L Thompson return 0; 3101d102b48SJeremy L Thompson } 3111d102b48SJeremy L Thompson 3121d102b48SJeremy L Thompson /** 313b7ec98d8SJeremy L Thompson @brief Assemble the diagonal of a square linear Operator 314b7ec98d8SJeremy L Thompson 315b7ec98d8SJeremy L Thompson This returns a CeedVector containing the diagonal of a linear CeedOperator. 316b7ec98d8SJeremy L Thompson 317b7ec98d8SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 318b7ec98d8SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedOperator diagonal 319b7ec98d8SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 320b7ec98d8SJeremy L Thompson CEED_REQUEST_IMMEDIATE 321b7ec98d8SJeremy L Thompson 322b7ec98d8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 323b7ec98d8SJeremy L Thompson 324b7ec98d8SJeremy L Thompson @ref Basic 325b7ec98d8SJeremy L Thompson **/ 3267f823360Sjeremylt int CeedOperatorAssembleLinearDiagonal(CeedOperator op, CeedVector *assembled, 3277f823360Sjeremylt CeedRequest *request) { 328b7ec98d8SJeremy L Thompson int ierr; 329b7ec98d8SJeremy L Thompson Ceed ceed = op->ceed; 330b7ec98d8SJeremy L Thompson CeedQFunction qf = op->qf; 331b7ec98d8SJeremy L Thompson 332b7ec98d8SJeremy L Thompson if (op->composite) { 333b7ec98d8SJeremy L Thompson // LCOV_EXCL_START 334b7ec98d8SJeremy L Thompson return CeedError(ceed, 1, "Cannot assemble QFunction for composite operator"); 335b7ec98d8SJeremy L Thompson // LCOV_EXCL_STOP 336b7ec98d8SJeremy L Thompson } else { 337b7ec98d8SJeremy L Thompson if (op->nfields == 0) 338b7ec98d8SJeremy L Thompson // LCOV_EXCL_START 339b7ec98d8SJeremy L Thompson return CeedError(ceed, 1, "No operator fields set"); 340b7ec98d8SJeremy L Thompson // LCOV_EXCL_STOP 341b7ec98d8SJeremy L Thompson if (op->nfields < qf->numinputfields + qf->numoutputfields) 342b7ec98d8SJeremy L Thompson // LCOV_EXCL_START 343b7ec98d8SJeremy L Thompson return CeedError( ceed, 1, "Not all operator fields set"); 344b7ec98d8SJeremy L Thompson // LCOV_EXCL_STOP 345b7ec98d8SJeremy L Thompson if (op->numelements == 0) 346b7ec98d8SJeremy L Thompson // LCOV_EXCL_START 347b7ec98d8SJeremy L Thompson return CeedError(ceed, 1, "At least one restriction required"); 348b7ec98d8SJeremy L Thompson // LCOV_EXCL_STOP 349b7ec98d8SJeremy L Thompson if (op->numqpoints == 0) 350b7ec98d8SJeremy L Thompson // LCOV_EXCL_START 351b7ec98d8SJeremy L Thompson return CeedError(ceed, 1, "At least one non-collocated basis required"); 352b7ec98d8SJeremy L Thompson // LCOV_EXCL_STOP 353b7ec98d8SJeremy L Thompson } 354b7ec98d8SJeremy L Thompson 355b7ec98d8SJeremy L Thompson // Use backend version, if available 356b7ec98d8SJeremy L Thompson if (op->AssembleLinearDiagonal) { 357b7ec98d8SJeremy L Thompson ierr = op->AssembleLinearDiagonal(op, assembled, request); CeedChk(ierr); 358b7ec98d8SJeremy L Thompson return 0; 359b7ec98d8SJeremy L Thompson } 360b7ec98d8SJeremy L Thompson 361b7ec98d8SJeremy L Thompson // Assemble QFunction 362b7ec98d8SJeremy L Thompson CeedVector assembledqf; 363b7ec98d8SJeremy L Thompson CeedElemRestriction rstr; 364b7ec98d8SJeremy L Thompson ierr = CeedOperatorAssembleLinearQFunction(op, &assembledqf, &rstr, request); 365b7ec98d8SJeremy L Thompson CeedChk(ierr); 366b7ec98d8SJeremy L Thompson ierr = CeedElemRestrictionDestroy(&rstr); CeedChk(ierr); 367b7ec98d8SJeremy L Thompson 368b7ec98d8SJeremy L Thompson // Determine active input basis 369*112e3f70Sjeremylt CeedInt numemodein = 0, ncomp, dim = 1; 370b7ec98d8SJeremy L Thompson CeedEvalMode *emodein = NULL; 371*112e3f70Sjeremylt CeedBasis basisin = NULL; 372*112e3f70Sjeremylt CeedElemRestriction rstrin = NULL; 373b7ec98d8SJeremy L Thompson for (CeedInt i=0; i<qf->numinputfields; i++) 374b7ec98d8SJeremy L Thompson if (op->inputfields[i]->vec == CEED_VECTOR_ACTIVE) { 375b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetBasis(op->inputfields[i], &basisin); 376b7ec98d8SJeremy L Thompson CeedChk(ierr); 377b7ec98d8SJeremy L Thompson ierr = CeedBasisGetNumComponents(basisin, &ncomp); CeedChk(ierr); 378b7ec98d8SJeremy L Thompson ierr = CeedBasisGetDimension(basisin, &dim); CeedChk(ierr); 379b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetElemRestriction(op->inputfields[i], &rstrin); 380b7ec98d8SJeremy L Thompson CeedChk(ierr); 381b7ec98d8SJeremy L Thompson CeedEvalMode emode; 382b7ec98d8SJeremy L Thompson ierr = CeedQFunctionFieldGetEvalMode(qf->inputfields[i], &emode); 383b7ec98d8SJeremy L Thompson CeedChk(ierr); 384b7ec98d8SJeremy L Thompson switch (emode) { 385b7ec98d8SJeremy L Thompson case CEED_EVAL_NONE: 386b7ec98d8SJeremy L Thompson case CEED_EVAL_INTERP: 387b7ec98d8SJeremy L Thompson ierr = CeedRealloc(numemodein + 1, &emodein); CeedChk(ierr); 388b7ec98d8SJeremy L Thompson emodein[numemodein] = emode; 389b7ec98d8SJeremy L Thompson numemodein += 1; 390b7ec98d8SJeremy L Thompson break; 391b7ec98d8SJeremy L Thompson case CEED_EVAL_GRAD: 392b7ec98d8SJeremy L Thompson ierr = CeedRealloc(numemodein + dim, &emodein); CeedChk(ierr); 393b7ec98d8SJeremy L Thompson for (CeedInt d=0; d<dim; d++) 394b7ec98d8SJeremy L Thompson emodein[numemodein+d] = emode; 395b7ec98d8SJeremy L Thompson numemodein += dim; 396b7ec98d8SJeremy L Thompson break; 397b7ec98d8SJeremy L Thompson case CEED_EVAL_WEIGHT: 398b7ec98d8SJeremy L Thompson case CEED_EVAL_DIV: 399b7ec98d8SJeremy L Thompson case CEED_EVAL_CURL: 400b7ec98d8SJeremy L Thompson break; // Caught by QF Assembly 401b7ec98d8SJeremy L Thompson } 402b7ec98d8SJeremy L Thompson } 403b7ec98d8SJeremy L Thompson 404b7ec98d8SJeremy L Thompson // Determine active output basis 405b7ec98d8SJeremy L Thompson CeedInt numemodeout = 0; 406b7ec98d8SJeremy L Thompson CeedEvalMode *emodeout = NULL; 407*112e3f70Sjeremylt CeedBasis basisout = NULL; 408*112e3f70Sjeremylt CeedElemRestriction rstrout = NULL; 409*112e3f70Sjeremylt CeedTransposeMode lmodeout = CEED_NOTRANSPOSE; 410b7ec98d8SJeremy L Thompson for (CeedInt i=0; i<qf->numoutputfields; i++) 411b7ec98d8SJeremy L Thompson if (op->outputfields[i]->vec == CEED_VECTOR_ACTIVE) { 412b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetBasis(op->outputfields[i], &basisout); 413b7ec98d8SJeremy L Thompson CeedChk(ierr); 414b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetElemRestriction(op->outputfields[i], &rstrout); 415b7ec98d8SJeremy L Thompson CeedChk(ierr); 416b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetLMode(op->outputfields[i], &lmodeout); 417b7ec98d8SJeremy L Thompson CeedChk(ierr); 418b7ec98d8SJeremy L Thompson CeedEvalMode emode; 419b7ec98d8SJeremy L Thompson ierr = CeedQFunctionFieldGetEvalMode(qf->outputfields[i], &emode); 420b7ec98d8SJeremy L Thompson CeedChk(ierr); 421b7ec98d8SJeremy L Thompson switch (emode) { 422b7ec98d8SJeremy L Thompson case CEED_EVAL_NONE: 423b7ec98d8SJeremy L Thompson case CEED_EVAL_INTERP: 424b7ec98d8SJeremy L Thompson ierr = CeedRealloc(numemodeout + 1, &emodeout); CeedChk(ierr); 425b7ec98d8SJeremy L Thompson emodeout[numemodeout] = emode; 426b7ec98d8SJeremy L Thompson numemodeout += 1; 427b7ec98d8SJeremy L Thompson break; 428b7ec98d8SJeremy L Thompson case CEED_EVAL_GRAD: 429b7ec98d8SJeremy L Thompson ierr = CeedRealloc(numemodeout + dim, &emodeout); CeedChk(ierr); 430b7ec98d8SJeremy L Thompson for (CeedInt d=0; d<dim; d++) 431b7ec98d8SJeremy L Thompson emodeout[numemodeout+d] = emode; 432b7ec98d8SJeremy L Thompson numemodeout += dim; 433b7ec98d8SJeremy L Thompson break; 434b7ec98d8SJeremy L Thompson case CEED_EVAL_WEIGHT: 435b7ec98d8SJeremy L Thompson case CEED_EVAL_DIV: 436b7ec98d8SJeremy L Thompson case CEED_EVAL_CURL: 437b7ec98d8SJeremy L Thompson break; // Caught by QF Assembly 438b7ec98d8SJeremy L Thompson } 439b7ec98d8SJeremy L Thompson } 440b7ec98d8SJeremy L Thompson 441b7ec98d8SJeremy L Thompson // Create diagonal vector 442b7ec98d8SJeremy L Thompson CeedVector elemdiag; 443b7ec98d8SJeremy L Thompson ierr = CeedElemRestrictionCreateVector(rstrin, assembled, &elemdiag); 444b7ec98d8SJeremy L Thompson CeedChk(ierr); 445b7ec98d8SJeremy L Thompson 446b7ec98d8SJeremy L Thompson // Assemble element operator diagonals 447b7ec98d8SJeremy L Thompson CeedScalar *elemdiagarray, *assembledqfarray; 448b7ec98d8SJeremy L Thompson ierr = CeedVectorSetValue(elemdiag, 0.0); CeedChk(ierr); 449b7ec98d8SJeremy L Thompson ierr = CeedVectorGetArray(elemdiag, CEED_MEM_HOST, &elemdiagarray); 450b7ec98d8SJeremy L Thompson CeedChk(ierr); 451b7ec98d8SJeremy L Thompson ierr = CeedVectorGetArray(assembledqf, CEED_MEM_HOST, &assembledqfarray); 452b7ec98d8SJeremy L Thompson CeedChk(ierr); 453b7ec98d8SJeremy L Thompson CeedInt nelem, nnodes, nqpts; 454b7ec98d8SJeremy L Thompson ierr = CeedElemRestrictionGetNumElements(rstrin, &nelem); CeedChk(ierr); 455b7ec98d8SJeremy L Thompson ierr = CeedBasisGetNumNodes(basisin, &nnodes); CeedChk(ierr); 456b7ec98d8SJeremy L Thompson ierr = CeedBasisGetNumQuadraturePoints(basisin, &nqpts); CeedChk(ierr); 457b7ec98d8SJeremy L Thompson // Compute the diagonal of B^T D B 458b7ec98d8SJeremy L Thompson // Each node, qpt pair 459b7ec98d8SJeremy L Thompson for (CeedInt n=0; n<nnodes; n++) 460b7ec98d8SJeremy L Thompson for (CeedInt q=0; q<nqpts; q++) { 461b7ec98d8SJeremy L Thompson CeedInt dout = -1; 462b7ec98d8SJeremy L Thompson // Each basis eval mode pair 463b7ec98d8SJeremy L Thompson for (CeedInt eout=0; eout<numemodeout; eout++) { 464b7ec98d8SJeremy L Thompson CeedScalar bt = 1.0; 465b7ec98d8SJeremy L Thompson if (emodeout[eout] == CEED_EVAL_GRAD) 466b7ec98d8SJeremy L Thompson dout += 1; 467b7ec98d8SJeremy L Thompson ierr = CeedBasisGetValue(basisout, emodeout[eout], q, n, dout, &bt); 468b7ec98d8SJeremy L Thompson CeedChk(ierr); 469b7ec98d8SJeremy L Thompson CeedInt din = -1; 470b7ec98d8SJeremy L Thompson for (CeedInt ein=0; ein<numemodein; ein++) { 471b7ec98d8SJeremy L Thompson CeedScalar b = 0.0; 472b7ec98d8SJeremy L Thompson if (emodein[ein] == CEED_EVAL_GRAD) 473b7ec98d8SJeremy L Thompson din += 1; 474b7ec98d8SJeremy L Thompson ierr = CeedBasisGetValue(basisin, emodein[ein], q, n, din, &b); 475b7ec98d8SJeremy L Thompson CeedChk(ierr); 476b7ec98d8SJeremy L Thompson // Each element and component 477b7ec98d8SJeremy L Thompson for (CeedInt e=0; e<nelem; e++) 478b7ec98d8SJeremy L Thompson for (CeedInt cout=0; cout<ncomp; cout++) { 479b7ec98d8SJeremy L Thompson CeedScalar db = 0.0; 480b7ec98d8SJeremy L Thompson for (CeedInt cin=0; cin<ncomp; cin++) 481b7ec98d8SJeremy L Thompson db += assembledqfarray[((((e*numemodein+ein)*ncomp+cin)* 482b7ec98d8SJeremy L Thompson numemodeout+eout)*ncomp+cout)*nqpts+q]*b; 483b7ec98d8SJeremy L Thompson elemdiagarray[(e*ncomp+cout)*nnodes+n] += bt * db; 484b7ec98d8SJeremy L Thompson } 485b7ec98d8SJeremy L Thompson } 486b7ec98d8SJeremy L Thompson } 487b7ec98d8SJeremy L Thompson } 488b7ec98d8SJeremy L Thompson 489b7ec98d8SJeremy L Thompson ierr = CeedVectorRestoreArray(elemdiag, &elemdiagarray); CeedChk(ierr); 490b7ec98d8SJeremy L Thompson ierr = CeedVectorRestoreArray(assembledqf, &assembledqfarray); CeedChk(ierr); 491b7ec98d8SJeremy L Thompson 492b7ec98d8SJeremy L Thompson // Assemble local operator diagonal 493b7ec98d8SJeremy L Thompson ierr = CeedVectorSetValue(*assembled, 0.0); CeedChk(ierr); 494b7ec98d8SJeremy L Thompson ierr = CeedElemRestrictionApply(rstrout, CEED_TRANSPOSE, lmodeout, elemdiag, 495b7ec98d8SJeremy L Thompson *assembled, request); CeedChk(ierr); 496b7ec98d8SJeremy L Thompson 497b7ec98d8SJeremy L Thompson // Cleanup 498b7ec98d8SJeremy L Thompson ierr = CeedVectorDestroy(&assembledqf); CeedChk(ierr); 499b7ec98d8SJeremy L Thompson ierr = CeedVectorDestroy(&elemdiag); CeedChk(ierr); 500b7ec98d8SJeremy L Thompson ierr = CeedFree(&emodein); CeedChk(ierr); 501b7ec98d8SJeremy L Thompson ierr = CeedFree(&emodeout); CeedChk(ierr); 502b7ec98d8SJeremy L Thompson 503b7ec98d8SJeremy L Thompson return 0; 504b7ec98d8SJeremy L Thompson } 505b7ec98d8SJeremy L Thompson 506b7ec98d8SJeremy L Thompson /** 507b11c1e72Sjeremylt @brief Apply CeedOperator to a vector 508d7b241e6Sjeremylt 509d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 510d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 511d7b241e6Sjeremylt CeedOperatorSetField(). 512d7b241e6Sjeremylt 513d7b241e6Sjeremylt @param op CeedOperator to apply 514b11c1e72Sjeremylt @param[in] in CeedVector containing input state or NULL if there are no 515b11c1e72Sjeremylt active inputs 516b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 517d7b241e6Sjeremylt distinct from @a in) or NULL if there are no active outputs 518d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 519d7b241e6Sjeremylt CEED_REQUEST_IMMEDIATE 520b11c1e72Sjeremylt 521b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 522dfdf5a53Sjeremylt 523dfdf5a53Sjeremylt @ref Basic 524b11c1e72Sjeremylt **/ 525d7b241e6Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, 526d7b241e6Sjeremylt CeedVector out, CeedRequest *request) { 527d7b241e6Sjeremylt int ierr; 528d7b241e6Sjeremylt Ceed ceed = op->ceed; 529d7b241e6Sjeremylt CeedQFunction qf = op->qf; 530d7b241e6Sjeremylt 53152d6035fSJeremy L Thompson if (op->composite) { 532c042f62fSJeremy L Thompson if (!op->numsub) 533c042f62fSJeremy L Thompson // LCOV_EXCL_START 534c042f62fSJeremy L Thompson return CeedError(ceed, 1, "No suboperators set"); 535c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 53652d6035fSJeremy L Thompson } else { 537c042f62fSJeremy L Thompson if (op->nfields == 0) 538c042f62fSJeremy L Thompson // LCOV_EXCL_START 539c042f62fSJeremy L Thompson return CeedError(ceed, 1, "No operator fields set"); 540c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 541c042f62fSJeremy L Thompson if (op->nfields < qf->numinputfields + qf->numoutputfields) 542c042f62fSJeremy L Thompson // LCOV_EXCL_START 543c042f62fSJeremy L Thompson return CeedError(ceed, 1, "Not all operator fields set"); 544c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 545c042f62fSJeremy L Thompson if (op->numelements == 0) 546c042f62fSJeremy L Thompson // LCOV_EXCL_START 547c042f62fSJeremy L Thompson return CeedError(ceed, 1,"At least one restriction required"); 548c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 549c042f62fSJeremy L Thompson if (op->numqpoints == 0) 550c042f62fSJeremy L Thompson // LCOV_EXCL_START 551c042f62fSJeremy L Thompson return CeedError(ceed, 1,"At least one non-collocated basis required"); 552c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 55352d6035fSJeremy L Thompson } 554d7b241e6Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 555d7b241e6Sjeremylt return 0; 556d7b241e6Sjeremylt } 557d7b241e6Sjeremylt 558d7b241e6Sjeremylt /** 5594ce2993fSjeremylt @brief Get the Ceed associated with a CeedOperator 5604ce2993fSjeremylt 5614ce2993fSjeremylt @param op CeedOperator 5624ce2993fSjeremylt @param[out] ceed Variable to store Ceed 5634ce2993fSjeremylt 5644ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5654ce2993fSjeremylt 56623617272Sjeremylt @ref Advanced 5674ce2993fSjeremylt **/ 5684ce2993fSjeremylt 5694ce2993fSjeremylt int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 5704ce2993fSjeremylt *ceed = op->ceed; 5714ce2993fSjeremylt return 0; 5724ce2993fSjeremylt } 5734ce2993fSjeremylt 5744ce2993fSjeremylt /** 5754ce2993fSjeremylt @brief Get the number of elements associated with a CeedOperator 5764ce2993fSjeremylt 5774ce2993fSjeremylt @param op CeedOperator 5784ce2993fSjeremylt @param[out] numelem Variable to store number of elements 5794ce2993fSjeremylt 5804ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5814ce2993fSjeremylt 58223617272Sjeremylt @ref Advanced 5834ce2993fSjeremylt **/ 5844ce2993fSjeremylt 5854ce2993fSjeremylt int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) { 58652d6035fSJeremy L Thompson if (op->composite) 587c042f62fSJeremy L Thompson // LCOV_EXCL_START 58852d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 589c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 59052d6035fSJeremy L Thompson 5914ce2993fSjeremylt *numelem = op->numelements; 5924ce2993fSjeremylt return 0; 5934ce2993fSjeremylt } 5944ce2993fSjeremylt 5954ce2993fSjeremylt /** 5964ce2993fSjeremylt @brief Get the number of quadrature points associated with a CeedOperator 5974ce2993fSjeremylt 5984ce2993fSjeremylt @param op CeedOperator 5994ce2993fSjeremylt @param[out] numqpts Variable to store vector number of quadrature points 6004ce2993fSjeremylt 6014ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6024ce2993fSjeremylt 60323617272Sjeremylt @ref Advanced 6044ce2993fSjeremylt **/ 6054ce2993fSjeremylt 6064ce2993fSjeremylt int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) { 60752d6035fSJeremy L Thompson if (op->composite) 608c042f62fSJeremy L Thompson // LCOV_EXCL_START 60952d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 610c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 61152d6035fSJeremy L Thompson 6124ce2993fSjeremylt *numqpts = op->numqpoints; 6134ce2993fSjeremylt return 0; 6144ce2993fSjeremylt } 6154ce2993fSjeremylt 6164ce2993fSjeremylt /** 6174ce2993fSjeremylt @brief Get the number of arguments associated with a CeedOperator 6184ce2993fSjeremylt 6194ce2993fSjeremylt @param op CeedOperator 6204ce2993fSjeremylt @param[out] numargs Variable to store vector number of arguments 6214ce2993fSjeremylt 6224ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6234ce2993fSjeremylt 62423617272Sjeremylt @ref Advanced 6254ce2993fSjeremylt **/ 6264ce2993fSjeremylt 6274ce2993fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) { 62852d6035fSJeremy L Thompson if (op->composite) 629c042f62fSJeremy L Thompson // LCOV_EXCL_START 63052d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operators"); 631c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 632c042f62fSJeremy L Thompson 6334ce2993fSjeremylt *numargs = op->nfields; 6344ce2993fSjeremylt return 0; 6354ce2993fSjeremylt } 6364ce2993fSjeremylt 6374ce2993fSjeremylt /** 6384ce2993fSjeremylt @brief Get the setup status of a CeedOperator 6394ce2993fSjeremylt 6404ce2993fSjeremylt @param op CeedOperator 641288c0443SJeremy L Thompson @param[out] setupdone Variable to store setup status 6424ce2993fSjeremylt 6434ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6444ce2993fSjeremylt 64523617272Sjeremylt @ref Advanced 6464ce2993fSjeremylt **/ 6474ce2993fSjeremylt 6484ce2993fSjeremylt int CeedOperatorGetSetupStatus(CeedOperator op, bool *setupdone) { 6494ce2993fSjeremylt *setupdone = op->setupdone; 6504ce2993fSjeremylt return 0; 6514ce2993fSjeremylt } 6524ce2993fSjeremylt 6534ce2993fSjeremylt /** 6544ce2993fSjeremylt @brief Get the QFunction associated with a CeedOperator 6554ce2993fSjeremylt 6564ce2993fSjeremylt @param op CeedOperator 6578c91a0c9SJeremy L Thompson @param[out] qf Variable to store QFunction 6584ce2993fSjeremylt 6594ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6604ce2993fSjeremylt 66123617272Sjeremylt @ref Advanced 6624ce2993fSjeremylt **/ 6634ce2993fSjeremylt 6644ce2993fSjeremylt int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 66552d6035fSJeremy L Thompson if (op->composite) 666c042f62fSJeremy L Thompson // LCOV_EXCL_START 66752d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 668c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 66952d6035fSJeremy L Thompson 6704ce2993fSjeremylt *qf = op->qf; 6714ce2993fSjeremylt return 0; 6724ce2993fSjeremylt } 6734ce2993fSjeremylt 6744ce2993fSjeremylt /** 67552d6035fSJeremy L Thompson @brief Get the number of suboperators associated with a CeedOperator 67652d6035fSJeremy L Thompson 67752d6035fSJeremy L Thompson @param op CeedOperator 67852d6035fSJeremy L Thompson @param[out] numsub Variable to store number of suboperators 67952d6035fSJeremy L Thompson 68052d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 68152d6035fSJeremy L Thompson 68252d6035fSJeremy L Thompson @ref Advanced 68352d6035fSJeremy L Thompson **/ 68452d6035fSJeremy L Thompson 68552d6035fSJeremy L Thompson int CeedOperatorGetNumSub(CeedOperator op, CeedInt *numsub) { 686c042f62fSJeremy L Thompson if (!op->composite) 687c042f62fSJeremy L Thompson // LCOV_EXCL_START 688c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 689c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 69052d6035fSJeremy L Thompson 69152d6035fSJeremy L Thompson *numsub = op->numsub; 69252d6035fSJeremy L Thompson return 0; 69352d6035fSJeremy L Thompson } 69452d6035fSJeremy L Thompson 69552d6035fSJeremy L Thompson /** 69652d6035fSJeremy L Thompson @brief Get the list of suboperators associated with a CeedOperator 69752d6035fSJeremy L Thompson 69852d6035fSJeremy L Thompson @param op CeedOperator 69952d6035fSJeremy L Thompson @param[out] suboperators Variable to store list of suboperators 70052d6035fSJeremy L Thompson 70152d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 70252d6035fSJeremy L Thompson 70352d6035fSJeremy L Thompson @ref Advanced 70452d6035fSJeremy L Thompson **/ 70552d6035fSJeremy L Thompson 70652d6035fSJeremy L Thompson int CeedOperatorGetSubList(CeedOperator op, CeedOperator* *suboperators) { 707c042f62fSJeremy L Thompson if (!op->composite) 708c042f62fSJeremy L Thompson // LCOV_EXCL_START 709c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 710c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 71152d6035fSJeremy L Thompson 71252d6035fSJeremy L Thompson *suboperators = op->suboperators; 71352d6035fSJeremy L Thompson return 0; 71452d6035fSJeremy L Thompson } 71552d6035fSJeremy L Thompson 71652d6035fSJeremy L Thompson /** 717fe2413ffSjeremylt @brief Set the backend data of a CeedOperator 718fe2413ffSjeremylt 719fe2413ffSjeremylt @param[out] op CeedOperator 720fe2413ffSjeremylt @param data Data to set 721fe2413ffSjeremylt 722fe2413ffSjeremylt @return An error code: 0 - success, otherwise - failure 723fe2413ffSjeremylt 724fe2413ffSjeremylt @ref Advanced 725fe2413ffSjeremylt **/ 726fe2413ffSjeremylt 727fe2413ffSjeremylt int CeedOperatorSetData(CeedOperator op, void* *data) { 728fe2413ffSjeremylt op->data = *data; 729fe2413ffSjeremylt return 0; 730fe2413ffSjeremylt } 731fe2413ffSjeremylt 732fe2413ffSjeremylt /** 7334ce2993fSjeremylt @brief Get the backend data of a CeedOperator 7344ce2993fSjeremylt 7354ce2993fSjeremylt @param op CeedOperator 7364ce2993fSjeremylt @param[out] data Variable to store data 7374ce2993fSjeremylt 7384ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7394ce2993fSjeremylt 74023617272Sjeremylt @ref Advanced 7414ce2993fSjeremylt **/ 7424ce2993fSjeremylt 7434ce2993fSjeremylt int CeedOperatorGetData(CeedOperator op, void* *data) { 7444ce2993fSjeremylt *data = op->data; 7454ce2993fSjeremylt return 0; 7464ce2993fSjeremylt } 7474ce2993fSjeremylt 7484ce2993fSjeremylt /** 7494ce2993fSjeremylt @brief Set the setup flag of a CeedOperator to True 7504ce2993fSjeremylt 7514ce2993fSjeremylt @param op CeedOperator 7524ce2993fSjeremylt 7534ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7544ce2993fSjeremylt 75523617272Sjeremylt @ref Advanced 7564ce2993fSjeremylt **/ 7574ce2993fSjeremylt 7584ce2993fSjeremylt int CeedOperatorSetSetupDone(CeedOperator op) { 7594ce2993fSjeremylt op->setupdone = 1; 7604ce2993fSjeremylt return 0; 7614ce2993fSjeremylt } 7624ce2993fSjeremylt 7634ce2993fSjeremylt /** 764d1bcdac9Sjeremylt @brief Get the CeedOperatorFields of a CeedOperator 765d1bcdac9Sjeremylt 766d1bcdac9Sjeremylt @param op CeedOperator 767d1bcdac9Sjeremylt @param[out] inputfields Variable to store inputfields 768d1bcdac9Sjeremylt @param[out] outputfields Variable to store outputfields 769d1bcdac9Sjeremylt 770d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 771d1bcdac9Sjeremylt 772d1bcdac9Sjeremylt @ref Advanced 773d1bcdac9Sjeremylt **/ 774d1bcdac9Sjeremylt 775d1bcdac9Sjeremylt int CeedOperatorGetFields(CeedOperator op, 776d1bcdac9Sjeremylt CeedOperatorField* *inputfields, 777d1bcdac9Sjeremylt CeedOperatorField* *outputfields) { 77852d6035fSJeremy L Thompson if (op->composite) 779c042f62fSJeremy L Thompson // LCOV_EXCL_START 78052d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 781c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 78252d6035fSJeremy L Thompson 783d1bcdac9Sjeremylt if (inputfields) *inputfields = op->inputfields; 784d1bcdac9Sjeremylt if (outputfields) *outputfields = op->outputfields; 785d1bcdac9Sjeremylt return 0; 786d1bcdac9Sjeremylt } 787d1bcdac9Sjeremylt 788d1bcdac9Sjeremylt /** 7894dccadb6Sjeremylt @brief Get the L vector CeedTransposeMode of a CeedOperatorField 7904dccadb6Sjeremylt 7914dccadb6Sjeremylt @param opfield CeedOperatorField 7924dccadb6Sjeremylt @param[out] lmode Variable to store CeedTransposeMode 7934dccadb6Sjeremylt 7944dccadb6Sjeremylt @return An error code: 0 - success, otherwise - failure 7954dccadb6Sjeremylt 7964dccadb6Sjeremylt @ref Advanced 7974dccadb6Sjeremylt **/ 7984dccadb6Sjeremylt 7994dccadb6Sjeremylt int CeedOperatorFieldGetLMode(CeedOperatorField opfield, 8004dccadb6Sjeremylt CeedTransposeMode *lmode) { 801fe2413ffSjeremylt *lmode = opfield->lmode; 8024dccadb6Sjeremylt return 0; 8032b8e417aSjeremylt } 8042b8e417aSjeremylt 8052b8e417aSjeremylt /** 806d1bcdac9Sjeremylt @brief Get the CeedElemRestriction of a CeedOperatorField 807d1bcdac9Sjeremylt 808d1bcdac9Sjeremylt @param opfield CeedOperatorField 809d1bcdac9Sjeremylt @param[out] rstr Variable to store CeedElemRestriction 810d1bcdac9Sjeremylt 811d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 812d1bcdac9Sjeremylt 813d1bcdac9Sjeremylt @ref Advanced 814d1bcdac9Sjeremylt **/ 815d1bcdac9Sjeremylt 816d1bcdac9Sjeremylt int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield, 817d1bcdac9Sjeremylt CeedElemRestriction *rstr) { 818fe2413ffSjeremylt *rstr = opfield->Erestrict; 819d1bcdac9Sjeremylt return 0; 820d1bcdac9Sjeremylt } 821d1bcdac9Sjeremylt 822d1bcdac9Sjeremylt /** 823d1bcdac9Sjeremylt @brief Get the CeedBasis of a CeedOperatorField 824d1bcdac9Sjeremylt 825d1bcdac9Sjeremylt @param opfield CeedOperatorField 826d1bcdac9Sjeremylt @param[out] basis Variable to store CeedBasis 827d1bcdac9Sjeremylt 828d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 829d1bcdac9Sjeremylt 830d1bcdac9Sjeremylt @ref Advanced 831d1bcdac9Sjeremylt **/ 832d1bcdac9Sjeremylt 833d1bcdac9Sjeremylt int CeedOperatorFieldGetBasis(CeedOperatorField opfield, 834d1bcdac9Sjeremylt CeedBasis *basis) { 835fe2413ffSjeremylt *basis = opfield->basis; 836d1bcdac9Sjeremylt return 0; 837d1bcdac9Sjeremylt } 838d1bcdac9Sjeremylt 839d1bcdac9Sjeremylt /** 840d1bcdac9Sjeremylt @brief Get the CeedVector of a CeedOperatorField 841d1bcdac9Sjeremylt 842d1bcdac9Sjeremylt @param opfield CeedOperatorField 843d1bcdac9Sjeremylt @param[out] vec Variable to store CeedVector 844d1bcdac9Sjeremylt 845d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 846d1bcdac9Sjeremylt 847d1bcdac9Sjeremylt @ref Advanced 848d1bcdac9Sjeremylt **/ 849d1bcdac9Sjeremylt 850d1bcdac9Sjeremylt int CeedOperatorFieldGetVector(CeedOperatorField opfield, 851d1bcdac9Sjeremylt CeedVector *vec) { 852fe2413ffSjeremylt *vec = opfield->vec; 853d1bcdac9Sjeremylt return 0; 854d1bcdac9Sjeremylt } 855d1bcdac9Sjeremylt 856d1bcdac9Sjeremylt /** 857b11c1e72Sjeremylt @brief Destroy a CeedOperator 858d7b241e6Sjeremylt 859d7b241e6Sjeremylt @param op CeedOperator to destroy 860b11c1e72Sjeremylt 861b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 862dfdf5a53Sjeremylt 863dfdf5a53Sjeremylt @ref Basic 864b11c1e72Sjeremylt **/ 865d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 866d7b241e6Sjeremylt int ierr; 867d7b241e6Sjeremylt 868d7b241e6Sjeremylt if (!*op || --(*op)->refcount > 0) return 0; 869d7b241e6Sjeremylt if ((*op)->Destroy) { 870d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 871d7b241e6Sjeremylt } 872fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 873fe2413ffSjeremylt // Free fields 8741d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 87552d6035fSJeremy L Thompson if ((*op)->inputfields[i]) { 87671352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->inputfields[i]->Erestrict); 87771352a93Sjeremylt CeedChk(ierr); 87871352a93Sjeremylt if ((*op)->inputfields[i]->basis != CEED_BASIS_COLLOCATED) { 87971352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->inputfields[i]->basis); CeedChk(ierr); 88071352a93Sjeremylt } 88171352a93Sjeremylt if ((*op)->inputfields[i]->vec != CEED_VECTOR_ACTIVE && 88271352a93Sjeremylt (*op)->inputfields[i]->vec != CEED_VECTOR_NONE ) { 88371352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->inputfields[i]->vec); CeedChk(ierr); 88471352a93Sjeremylt } 885fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields[i]); CeedChk(ierr); 886fe2413ffSjeremylt } 8871d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 888d0eb30a5Sjeremylt if ((*op)->outputfields[i]) { 88971352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->outputfields[i]->Erestrict); 89071352a93Sjeremylt CeedChk(ierr); 89171352a93Sjeremylt if ((*op)->outputfields[i]->basis != CEED_BASIS_COLLOCATED) { 89271352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->outputfields[i]->basis); CeedChk(ierr); 89371352a93Sjeremylt } 89471352a93Sjeremylt if ((*op)->outputfields[i]->vec != CEED_VECTOR_ACTIVE && 89571352a93Sjeremylt (*op)->outputfields[i]->vec != CEED_VECTOR_NONE ) { 89671352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->outputfields[i]->vec); CeedChk(ierr); 89771352a93Sjeremylt } 898fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields[i]); CeedChk(ierr); 899fe2413ffSjeremylt } 90052d6035fSJeremy L Thompson // Destroy suboperators 9011d102b48SJeremy L Thompson for (int i=0; i<(*op)->numsub; i++) 90252d6035fSJeremy L Thompson if ((*op)->suboperators[i]) { 90352d6035fSJeremy L Thompson ierr = CeedOperatorDestroy(&(*op)->suboperators[i]); CeedChk(ierr); 90452d6035fSJeremy L Thompson } 905d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 906d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 907d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 908fe2413ffSjeremylt 909fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields); CeedChk(ierr); 910fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields); CeedChk(ierr); 91152d6035fSJeremy L Thompson ierr = CeedFree(&(*op)->suboperators); CeedChk(ierr); 912d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 913d7b241e6Sjeremylt return 0; 914d7b241e6Sjeremylt } 915d7b241e6Sjeremylt 916d7b241e6Sjeremylt /// @} 917