121617c04Sjeremylt // Copyright (c) 2017-2018, Lawrence Livermore National Security, LLC. 221617c04Sjeremylt // Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707. 321617c04Sjeremylt // All Rights reserved. See files LICENSE and NOTICE for details. 421617c04Sjeremylt // 521617c04Sjeremylt // This file is part of CEED, a collection of benchmarks, miniapps, software 621617c04Sjeremylt // libraries and APIs for efficient high-order finite element and spectral 721617c04Sjeremylt // element discretizations for exascale applications. For more information and 821617c04Sjeremylt // source code availability see http://github.com/ceed. 921617c04Sjeremylt // 1021617c04Sjeremylt // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 1121617c04Sjeremylt // a collaborative effort of two U.S. Department of Energy organizations (Office 1221617c04Sjeremylt // of Science and the National Nuclear Security Administration) responsible for 1321617c04Sjeremylt // the planning and preparation of a capable exascale ecosystem, including 1421617c04Sjeremylt // software, applications, hardware, advanced system engineering and early 1521617c04Sjeremylt // testbed platforms, in support of the nation's exascale computing imperative. 1621617c04Sjeremylt 1721617c04Sjeremylt #include <string.h> 1821617c04Sjeremylt #include "ceed-ref.h" 1921617c04Sjeremylt 2021617c04Sjeremylt static int CeedOperatorDestroy_Ref(CeedOperator op) { 2121617c04Sjeremylt int ierr; 224ce2993fSjeremylt CeedOperator_Ref *impl; 234ce2993fSjeremylt ierr = CeedOperatorGetData(op, (void*)&impl); CeedChk(ierr); 2421617c04Sjeremylt 25885ac19cSjeremylt for (CeedInt i=0; i<impl->numein+impl->numeout; i++) { 26885ac19cSjeremylt ierr = CeedVectorDestroy(&impl->evecs[i]); CeedChk(ierr); 27885ac19cSjeremylt } 28885ac19cSjeremylt ierr = CeedFree(&impl->evecs); CeedChk(ierr); 29885ac19cSjeremylt ierr = CeedFree(&impl->edata); CeedChk(ierr); 30885ac19cSjeremylt 31*aedaa0e5Sjeremylt for (CeedInt i=0; i<impl->numein; i++) { 32*aedaa0e5Sjeremylt ierr = CeedVectorDestroy(&impl->qvecsin[i]); CeedChk(ierr); 33885ac19cSjeremylt } 34*aedaa0e5Sjeremylt ierr = CeedFree(&impl->qvecsin); CeedChk(ierr); 35885ac19cSjeremylt 36*aedaa0e5Sjeremylt for (CeedInt i=0; i<impl->numeout; i++) { 37*aedaa0e5Sjeremylt ierr = CeedVectorDestroy(&impl->qvecsout[i]); CeedChk(ierr); 38*aedaa0e5Sjeremylt } 39*aedaa0e5Sjeremylt ierr = CeedFree(&impl->qvecsout); CeedChk(ierr); 40885ac19cSjeremylt 41fe2413ffSjeremylt ierr = CeedFree(&impl); CeedChk(ierr); 4221617c04Sjeremylt return 0; 4321617c04Sjeremylt } 4421617c04Sjeremylt 45885ac19cSjeremylt /* 46885ac19cSjeremylt Setup infields or outfields 47885ac19cSjeremylt */ 48fe2413ffSjeremylt static int CeedOperatorSetupFields_Ref(CeedQFunction qf, CeedOperator op, 49*aedaa0e5Sjeremylt bool inOrOut, CeedVector *evecs, 50*aedaa0e5Sjeremylt CeedVector *qvecs, CeedInt starte, 51135a076eSjeremylt CeedInt numfields, CeedInt Q) { 52*aedaa0e5Sjeremylt CeedInt dim, ierr, ncomp; 53*aedaa0e5Sjeremylt Ceed ceed; 54*aedaa0e5Sjeremylt ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 55d1bcdac9Sjeremylt CeedBasis basis; 56d1bcdac9Sjeremylt CeedElemRestriction Erestrict; 57*aedaa0e5Sjeremylt CeedOperatorField *opfields; 58*aedaa0e5Sjeremylt CeedQFunctionField *qffields; 59fe2413ffSjeremylt if (inOrOut) { 60*aedaa0e5Sjeremylt ierr = CeedOperatorGetFields(op, NULL, &opfields); 61fe2413ffSjeremylt CeedChk(ierr); 62*aedaa0e5Sjeremylt ierr = CeedQFunctionGetFields(qf, NULL, &qffields); 63fe2413ffSjeremylt CeedChk(ierr); 64fe2413ffSjeremylt } else { 65*aedaa0e5Sjeremylt ierr = CeedOperatorGetFields(op, &opfields, NULL); 66fe2413ffSjeremylt CeedChk(ierr); 67*aedaa0e5Sjeremylt ierr = CeedQFunctionGetFields(qf, &qffields, NULL); 68fe2413ffSjeremylt CeedChk(ierr); 69fe2413ffSjeremylt } 7021617c04Sjeremylt 71885ac19cSjeremylt // Loop over fields 72885ac19cSjeremylt for (CeedInt i=0; i<numfields; i++) { 73d1bcdac9Sjeremylt CeedEvalMode emode; 74*aedaa0e5Sjeremylt ierr = CeedQFunctionFieldGetEvalMode(qffields[i], &emode); CeedChk(ierr); 75135a076eSjeremylt 76135a076eSjeremylt if (emode != CEED_EVAL_WEIGHT) { 77*aedaa0e5Sjeremylt ierr = CeedOperatorFieldGetElemRestriction(opfields[i], &Erestrict); 78d1bcdac9Sjeremylt CeedChk(ierr); 79d1bcdac9Sjeremylt ierr = CeedElemRestrictionCreateVector(Erestrict, NULL, 80*aedaa0e5Sjeremylt &evecs[i+starte]); 81135a076eSjeremylt CeedChk(ierr); 82135a076eSjeremylt } 83135a076eSjeremylt 84885ac19cSjeremylt switch(emode) { 85885ac19cSjeremylt case CEED_EVAL_NONE: 86*aedaa0e5Sjeremylt ierr = CeedQFunctionFieldGetNumComponents(qffields[i], &ncomp); 87d1bcdac9Sjeremylt CeedChk(ierr); 88*aedaa0e5Sjeremylt ierr = CeedVectorCreate(ceed, Q*ncomp, &qvecs[i]); CeedChk(ierr); 89*aedaa0e5Sjeremylt break; 90*aedaa0e5Sjeremylt case CEED_EVAL_INTERP: 91*aedaa0e5Sjeremylt ierr = CeedQFunctionFieldGetNumComponents(qffields[i], &ncomp); 92*aedaa0e5Sjeremylt CeedChk(ierr); 93*aedaa0e5Sjeremylt ierr = CeedVectorCreate(ceed, Q*ncomp, &qvecs[i]); CeedChk(ierr); 94885ac19cSjeremylt break; 95885ac19cSjeremylt case CEED_EVAL_GRAD: 96*aedaa0e5Sjeremylt ierr = CeedOperatorFieldGetBasis(opfields[i], &basis); CeedChk(ierr); 97*aedaa0e5Sjeremylt ierr = CeedQFunctionFieldGetNumComponents(qffields[i], &ncomp); 98d1bcdac9Sjeremylt ierr = CeedBasisGetDimension(basis, &dim); CeedChk(ierr); 99*aedaa0e5Sjeremylt ierr = CeedVectorCreate(ceed, Q*ncomp*dim, &qvecs[i]); CeedChk(ierr); 100885ac19cSjeremylt break; 101885ac19cSjeremylt case CEED_EVAL_WEIGHT: // Only on input fields 102*aedaa0e5Sjeremylt ierr = CeedOperatorFieldGetBasis(opfields[i], &basis); CeedChk(ierr); 103*aedaa0e5Sjeremylt ierr = CeedVectorCreate(ceed, Q, &qvecs[i]); CeedChk(ierr); 104d1bcdac9Sjeremylt ierr = CeedBasisApply(basis, 1, CEED_NOTRANSPOSE, CEED_EVAL_WEIGHT, 105*aedaa0e5Sjeremylt NULL, qvecs[i]); CeedChk(ierr); 106885ac19cSjeremylt break; 107885ac19cSjeremylt case CEED_EVAL_DIV: 108885ac19cSjeremylt break; // Not implimented 109885ac19cSjeremylt case CEED_EVAL_CURL: 110885ac19cSjeremylt break; // Not implimented 11121617c04Sjeremylt } 112885ac19cSjeremylt } 11321617c04Sjeremylt return 0; 11421617c04Sjeremylt } 11521617c04Sjeremylt 116885ac19cSjeremylt /* 117885ac19cSjeremylt CeedOperator needs to connect all the named fields (be they active or passive) 118885ac19cSjeremylt to the named inputs and outputs of its CeedQFunction. 119885ac19cSjeremylt */ 120885ac19cSjeremylt static int CeedOperatorSetup_Ref(CeedOperator op) { 12121617c04Sjeremylt int ierr; 1224ce2993fSjeremylt bool setupdone; 1234ce2993fSjeremylt ierr = CeedOperatorGetSetupStatus(op, &setupdone); CeedChk(ierr); 1244ce2993fSjeremylt if (setupdone) return 0; 125*aedaa0e5Sjeremylt Ceed ceed; 126*aedaa0e5Sjeremylt ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 1274ce2993fSjeremylt CeedOperator_Ref *impl; 1284ce2993fSjeremylt ierr = CeedOperatorGetData(op, (void*)&impl); CeedChk(ierr); 1294ce2993fSjeremylt CeedQFunction qf; 1304ce2993fSjeremylt ierr = CeedOperatorGetQFunction(op, &qf); CeedChk(ierr); 1314ce2993fSjeremylt CeedInt Q, numinputfields, numoutputfields; 1324ce2993fSjeremylt ierr = CeedOperatorGetNumQuadraturePoints(op, &Q); CeedChk(ierr); 133a8de75f0Sjeremylt ierr = CeedQFunctionGetNumArgs(qf, &numinputfields, &numoutputfields); 134a8de75f0Sjeremylt CeedChk(ierr); 135d1bcdac9Sjeremylt CeedOperatorField *opinputfields, *opoutputfields; 136d1bcdac9Sjeremylt ierr = CeedOperatorGetFields(op, &opinputfields, &opoutputfields); 137d1bcdac9Sjeremylt CeedChk(ierr); 138d1bcdac9Sjeremylt CeedQFunctionField *qfinputfields, *qfoutputfields; 139d1bcdac9Sjeremylt ierr = CeedQFunctionGetFields(qf, &qfinputfields, &qfoutputfields); 140d1bcdac9Sjeremylt CeedChk(ierr); 141885ac19cSjeremylt 142885ac19cSjeremylt // Allocate 143*aedaa0e5Sjeremylt ierr = CeedCalloc(numinputfields + numoutputfields, &impl->evecs); 144*aedaa0e5Sjeremylt CeedChk(ierr); 145*aedaa0e5Sjeremylt ierr = CeedCalloc(numinputfields + numoutputfields, &impl->edata); 146885ac19cSjeremylt CeedChk(ierr); 147885ac19cSjeremylt 148*aedaa0e5Sjeremylt ierr = CeedCalloc(16, &impl->qvecsin); CeedChk(ierr); 149*aedaa0e5Sjeremylt ierr = CeedCalloc(16, &impl->qvecsout); CeedChk(ierr); 150885ac19cSjeremylt 151*aedaa0e5Sjeremylt impl->numein = numinputfields; impl->numeout = numoutputfields; 152885ac19cSjeremylt 153*aedaa0e5Sjeremylt // Set up infield and outfield evecs and qvecs 154885ac19cSjeremylt // Infields 155fe2413ffSjeremylt ierr = CeedOperatorSetupFields_Ref(qf, op, 0, 156*aedaa0e5Sjeremylt impl->evecs, impl->qvecsin, 0, 157*aedaa0e5Sjeremylt numinputfields, Q); 158*aedaa0e5Sjeremylt CeedChk(ierr); 159885ac19cSjeremylt 160885ac19cSjeremylt // Outfields 161fe2413ffSjeremylt ierr = CeedOperatorSetupFields_Ref(qf, op, 1, 162*aedaa0e5Sjeremylt impl->evecs, impl->qvecsout, 163*aedaa0e5Sjeremylt numinputfields, numoutputfields, Q); 164d1bcdac9Sjeremylt CeedChk(ierr); 165885ac19cSjeremylt 166*aedaa0e5Sjeremylt // Temporary Vector 167*aedaa0e5Sjeremylt ierr = CeedVectorCreate(ceed, 0, &impl->tempvec); CeedChk(ierr); 1687ca8db16Sjeremylt 1694ce2993fSjeremylt ierr = CeedOperatorSetSetupDone(op); CeedChk(ierr); 170885ac19cSjeremylt 171885ac19cSjeremylt return 0; 172885ac19cSjeremylt } 173885ac19cSjeremylt 174885ac19cSjeremylt static int CeedOperatorApply_Ref(CeedOperator op, CeedVector invec, 175885ac19cSjeremylt CeedVector outvec, CeedRequest *request) { 176885ac19cSjeremylt int ierr; 1774ce2993fSjeremylt CeedOperator_Ref *impl; 1784ce2993fSjeremylt ierr = CeedOperatorGetData(op, (void*)&impl); CeedChk(ierr); 1794ce2993fSjeremylt CeedQFunction qf; 1804ce2993fSjeremylt ierr = CeedOperatorGetQFunction(op, &qf); CeedChk(ierr); 181d1bcdac9Sjeremylt CeedInt Q, numelements, elemsize, numinputfields, numoutputfields, ncomp; 1824ce2993fSjeremylt ierr = CeedOperatorGetNumQuadraturePoints(op, &Q); CeedChk(ierr); 1834ce2993fSjeremylt ierr = CeedOperatorGetNumElements(op, &numelements); CeedChk(ierr); 1844ce2993fSjeremylt ierr= CeedQFunctionGetNumArgs(qf, &numinputfields, &numoutputfields); 1854ce2993fSjeremylt CeedChk(ierr); 1864dccadb6Sjeremylt CeedTransposeMode lmode; 187d1bcdac9Sjeremylt CeedOperatorField *opinputfields, *opoutputfields; 188d1bcdac9Sjeremylt ierr = CeedOperatorGetFields(op, &opinputfields, &opoutputfields); 189d1bcdac9Sjeremylt CeedChk(ierr); 190d1bcdac9Sjeremylt CeedQFunctionField *qfinputfields, *qfoutputfields; 191d1bcdac9Sjeremylt ierr = CeedQFunctionGetFields(qf, &qfinputfields, &qfoutputfields); 192d1bcdac9Sjeremylt CeedChk(ierr); 193d1bcdac9Sjeremylt CeedEvalMode emode; 194d1bcdac9Sjeremylt CeedVector vec; 195d1bcdac9Sjeremylt CeedBasis basis; 196d1bcdac9Sjeremylt CeedElemRestriction Erestrict; 197885ac19cSjeremylt 198885ac19cSjeremylt // Setup 199885ac19cSjeremylt ierr = CeedOperatorSetup_Ref(op); CeedChk(ierr); 200885ac19cSjeremylt 201885ac19cSjeremylt // Input Evecs and Restriction 2021a4ead9bSjeremylt for (CeedInt i=0; i<numinputfields; i++) { 203d1bcdac9Sjeremylt ierr = CeedQFunctionFieldGetEvalMode(qfinputfields[i], &emode); 204d1bcdac9Sjeremylt CeedChk(ierr); 205135a076eSjeremylt if (emode == CEED_EVAL_WEIGHT) { // Skip 206668048e2SJed Brown } else { 207d1bcdac9Sjeremylt // Get input vector 208d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetVector(opinputfields[i], &vec); CeedChk(ierr); 209d1bcdac9Sjeremylt if (vec == CEED_VECTOR_ACTIVE) 210d1bcdac9Sjeremylt vec = invec; 211668048e2SJed Brown // Restrict 212d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetElemRestriction(opinputfields[i], &Erestrict); 213d1bcdac9Sjeremylt CeedChk(ierr); 2144dccadb6Sjeremylt ierr = CeedOperatorFieldGetLMode(opinputfields[i], &lmode); CeedChk(ierr); 215d1bcdac9Sjeremylt ierr = CeedElemRestrictionApply(Erestrict, CEED_NOTRANSPOSE, 216d1bcdac9Sjeremylt lmode, vec, impl->evecs[i], 217668048e2SJed Brown request); CeedChk(ierr); 218668048e2SJed Brown // Get evec 219a2b73c81Sjeremylt ierr = CeedVectorGetArrayRead(impl->evecs[i], CEED_MEM_HOST, 220d1bcdac9Sjeremylt (const CeedScalar **) &impl->edata[i]); 221d1bcdac9Sjeremylt CeedChk(ierr); 222885ac19cSjeremylt } 223885ac19cSjeremylt } 224885ac19cSjeremylt 225885ac19cSjeremylt // Output Evecs 2261a4ead9bSjeremylt for (CeedInt i=0; i<numoutputfields; i++) { 227a2b73c81Sjeremylt ierr = CeedVectorGetArray(impl->evecs[i+impl->numein], CEED_MEM_HOST, 2281a4ead9bSjeremylt &impl->edata[i + numinputfields]); CeedChk(ierr); 229885ac19cSjeremylt } 230885ac19cSjeremylt 231885ac19cSjeremylt // Loop through elements 2324ce2993fSjeremylt for (CeedInt e=0; e<numelements; e++) { 233885ac19cSjeremylt // Input basis apply if needed 2341a4ead9bSjeremylt for (CeedInt i=0; i<numinputfields; i++) { 235135a076eSjeremylt // Get elemsize, emode, ncomp 236d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetElemRestriction(opinputfields[i], &Erestrict); 237d1bcdac9Sjeremylt CeedChk(ierr); 238d1bcdac9Sjeremylt ierr = CeedElemRestrictionGetElementSize(Erestrict, &elemsize); 239d1bcdac9Sjeremylt CeedChk(ierr); 240d1bcdac9Sjeremylt ierr = CeedQFunctionFieldGetEvalMode(qfinputfields[i], &emode); 241d1bcdac9Sjeremylt CeedChk(ierr); 242d1bcdac9Sjeremylt ierr = CeedQFunctionFieldGetNumComponents(qfinputfields[i], &ncomp); 243d1bcdac9Sjeremylt CeedChk(ierr); 244885ac19cSjeremylt // Basis action 245885ac19cSjeremylt switch(emode) { 246885ac19cSjeremylt case CEED_EVAL_NONE: 247*aedaa0e5Sjeremylt ierr = CeedVectorSetArray(impl->qvecsin[i], CEED_MEM_HOST, 248*aedaa0e5Sjeremylt CEED_USE_POINTER, 249*aedaa0e5Sjeremylt &impl->edata[i][e*Q*ncomp]); CeedChk(ierr); 250885ac19cSjeremylt break; 251885ac19cSjeremylt case CEED_EVAL_INTERP: 252d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetBasis(opinputfields[i], &basis); CeedChk(ierr); 253*aedaa0e5Sjeremylt ierr = CeedVectorSetArray(impl->tempvec, CEED_MEM_HOST, 254*aedaa0e5Sjeremylt CEED_USE_POINTER, 255*aedaa0e5Sjeremylt &impl->edata[i][e*elemsize*ncomp]); 256*aedaa0e5Sjeremylt CeedChk(ierr); 257d1bcdac9Sjeremylt ierr = CeedBasisApply(basis, 1, CEED_NOTRANSPOSE, 258*aedaa0e5Sjeremylt CEED_EVAL_INTERP, impl->tempvec, 259*aedaa0e5Sjeremylt impl->qvecsin[i]); CeedChk(ierr); 260885ac19cSjeremylt break; 261885ac19cSjeremylt case CEED_EVAL_GRAD: 262d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetBasis(opinputfields[i], &basis); CeedChk(ierr); 263*aedaa0e5Sjeremylt ierr = CeedVectorSetArray(impl->tempvec, CEED_MEM_HOST, 264*aedaa0e5Sjeremylt CEED_USE_POINTER, 265*aedaa0e5Sjeremylt &impl->edata[i][e*elemsize*ncomp]); 266*aedaa0e5Sjeremylt CeedChk(ierr); 267d1bcdac9Sjeremylt ierr = CeedBasisApply(basis, 1, CEED_NOTRANSPOSE, 268*aedaa0e5Sjeremylt CEED_EVAL_GRAD, impl->tempvec, 269*aedaa0e5Sjeremylt impl->qvecsin[i]); CeedChk(ierr); 270885ac19cSjeremylt break; 271885ac19cSjeremylt case CEED_EVAL_WEIGHT: 272885ac19cSjeremylt break; // No action 273885ac19cSjeremylt case CEED_EVAL_DIV: 274885ac19cSjeremylt break; // Not implimented 275885ac19cSjeremylt case CEED_EVAL_CURL: 276885ac19cSjeremylt break; // Not implimented 277885ac19cSjeremylt } 278885ac19cSjeremylt } 279885ac19cSjeremylt // Output pointers 2801a4ead9bSjeremylt for (CeedInt i=0; i<numoutputfields; i++) { 281d1bcdac9Sjeremylt ierr = CeedQFunctionFieldGetEvalMode(qfoutputfields[i], &emode); 282d1bcdac9Sjeremylt CeedChk(ierr); 283885ac19cSjeremylt if (emode == CEED_EVAL_NONE) { 284d1bcdac9Sjeremylt ierr = CeedQFunctionFieldGetNumComponents(qfoutputfields[i], &ncomp); 285d1bcdac9Sjeremylt CeedChk(ierr); 286*aedaa0e5Sjeremylt ierr = CeedVectorSetArray(impl->qvecsout[i], CEED_MEM_HOST, 287*aedaa0e5Sjeremylt CEED_USE_POINTER, 288*aedaa0e5Sjeremylt &impl->edata[i + numinputfields][e*Q*ncomp]); 289*aedaa0e5Sjeremylt CeedChk(ierr); 290885ac19cSjeremylt } 291885ac19cSjeremylt } 292885ac19cSjeremylt // Q function 293*aedaa0e5Sjeremylt ierr = CeedQFunctionApply(qf, Q, impl->qvecsin, impl->qvecsout); CeedChk(ierr); 294885ac19cSjeremylt 295885ac19cSjeremylt // Output basis apply if needed 2961a4ead9bSjeremylt for (CeedInt i=0; i<numoutputfields; i++) { 297135a076eSjeremylt // Get elemsize, emode, ncomp 298d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetElemRestriction(opoutputfields[i], &Erestrict); 299d1bcdac9Sjeremylt CeedChk(ierr); 300d1bcdac9Sjeremylt ierr = CeedElemRestrictionGetElementSize(Erestrict, &elemsize); 301d1bcdac9Sjeremylt CeedChk(ierr); 302d1bcdac9Sjeremylt ierr = CeedQFunctionFieldGetEvalMode(qfoutputfields[i], &emode); 303d1bcdac9Sjeremylt CeedChk(ierr); 304d1bcdac9Sjeremylt ierr = CeedQFunctionFieldGetNumComponents(qfoutputfields[i], &ncomp); 305d1bcdac9Sjeremylt CeedChk(ierr); 306885ac19cSjeremylt // Basis action 307885ac19cSjeremylt switch(emode) { 308885ac19cSjeremylt case CEED_EVAL_NONE: 309885ac19cSjeremylt break; // No action 310885ac19cSjeremylt case CEED_EVAL_INTERP: 311d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetBasis(opoutputfields[i], &basis); 312d1bcdac9Sjeremylt CeedChk(ierr); 313*aedaa0e5Sjeremylt ierr = CeedVectorSetArray(impl->tempvec, CEED_MEM_HOST, 314*aedaa0e5Sjeremylt CEED_USE_POINTER, 3151a4ead9bSjeremylt &impl->edata[i + numinputfields][e*elemsize*ncomp]); 316*aedaa0e5Sjeremylt ierr = CeedBasisApply(basis, 1, CEED_TRANSPOSE, 317*aedaa0e5Sjeremylt CEED_EVAL_INTERP, impl->qvecsout[i], 318*aedaa0e5Sjeremylt impl->tempvec); CeedChk(ierr); 319885ac19cSjeremylt break; 320885ac19cSjeremylt case CEED_EVAL_GRAD: 321d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetBasis(opoutputfields[i], &basis); 322d1bcdac9Sjeremylt CeedChk(ierr); 323*aedaa0e5Sjeremylt ierr = CeedVectorSetArray(impl->tempvec, CEED_MEM_HOST, 324*aedaa0e5Sjeremylt CEED_USE_POINTER, 325d1bcdac9Sjeremylt &impl->edata[i + numinputfields][e*elemsize*ncomp]); 326*aedaa0e5Sjeremylt ierr = CeedBasisApply(basis, 1, CEED_TRANSPOSE, 327*aedaa0e5Sjeremylt CEED_EVAL_GRAD, impl->qvecsout[i], 328*aedaa0e5Sjeremylt impl->tempvec); CeedChk(ierr); 329885ac19cSjeremylt break; 3304ce2993fSjeremylt case CEED_EVAL_WEIGHT: { 3314ce2993fSjeremylt Ceed ceed; 3324ce2993fSjeremylt ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 3334ce2993fSjeremylt return CeedError(ceed, 1, 3348d94b059Sjeremylt "CEED_EVAL_WEIGHT cannot be an output evaluation mode"); 335885ac19cSjeremylt break; // Should not occur 3364ce2993fSjeremylt } 337885ac19cSjeremylt case CEED_EVAL_DIV: 338885ac19cSjeremylt break; // Not implimented 339885ac19cSjeremylt case CEED_EVAL_CURL: 340885ac19cSjeremylt break; // Not implimented 341885ac19cSjeremylt } 342885ac19cSjeremylt } 343885ac19cSjeremylt } 344885ac19cSjeremylt 34542ecf959Sjeremylt // Zero lvecs 346d1bcdac9Sjeremylt for (CeedInt i=0; i<numoutputfields; i++) { 347d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetVector(opoutputfields[i], &vec); CeedChk(ierr); 348d1bcdac9Sjeremylt if (vec == CEED_VECTOR_ACTIVE) 349d1bcdac9Sjeremylt vec = outvec; 350d1bcdac9Sjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 35142ecf959Sjeremylt } 35242ecf959Sjeremylt 353885ac19cSjeremylt // Output restriction 3541a4ead9bSjeremylt for (CeedInt i=0; i<numoutputfields; i++) { 355a2b73c81Sjeremylt // Restore evec 356a2b73c81Sjeremylt ierr = CeedVectorRestoreArray(impl->evecs[i+impl->numein], 357d1bcdac9Sjeremylt &impl->edata[i + numinputfields]); 358d1bcdac9Sjeremylt CeedChk(ierr); 359d1bcdac9Sjeremylt // Get output vector 360d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetVector(opoutputfields[i], &vec); CeedChk(ierr); 361668048e2SJed Brown // Active 362d1bcdac9Sjeremylt if (vec == CEED_VECTOR_ACTIVE) 363d1bcdac9Sjeremylt vec = outvec; 3647ca8db16Sjeremylt // Restrict 365d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetElemRestriction(opoutputfields[i], &Erestrict); 366d1bcdac9Sjeremylt CeedChk(ierr); 3674dccadb6Sjeremylt ierr = CeedOperatorFieldGetLMode(opoutputfields[i], &lmode); CeedChk(ierr); 368d1bcdac9Sjeremylt ierr = CeedElemRestrictionApply(Erestrict, CEED_TRANSPOSE, 369d1bcdac9Sjeremylt lmode, impl->evecs[i+impl->numein], vec, 370668048e2SJed Brown request); CeedChk(ierr); 371885ac19cSjeremylt } 372885ac19cSjeremylt 3737ca8db16Sjeremylt // Restore input arrays 3741a4ead9bSjeremylt for (CeedInt i=0; i<numinputfields; i++) { 375d1bcdac9Sjeremylt ierr = CeedQFunctionFieldGetEvalMode(qfinputfields[i], &emode); 376d1bcdac9Sjeremylt CeedChk(ierr); 377135a076eSjeremylt if (emode == CEED_EVAL_WEIGHT) { // Skip 3787ca8db16Sjeremylt } else { 379a2b73c81Sjeremylt ierr = CeedVectorRestoreArrayRead(impl->evecs[i], 380d1bcdac9Sjeremylt (const CeedScalar **) &impl->edata[i]); 381d1bcdac9Sjeremylt CeedChk(ierr); 3827ca8db16Sjeremylt } 3837ca8db16Sjeremylt } 3847ca8db16Sjeremylt 38521617c04Sjeremylt return 0; 38621617c04Sjeremylt } 38721617c04Sjeremylt 38821617c04Sjeremylt int CeedOperatorCreate_Ref(CeedOperator op) { 38921617c04Sjeremylt int ierr; 390fe2413ffSjeremylt Ceed ceed; 391fe2413ffSjeremylt ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 3924ce2993fSjeremylt CeedOperator_Ref *impl; 39321617c04Sjeremylt 39421617c04Sjeremylt ierr = CeedCalloc(1, &impl); CeedChk(ierr); 395fe2413ffSjeremylt ierr = CeedOperatorSetData(op, (void*)&impl); 396fe2413ffSjeremylt 397fe2413ffSjeremylt ierr = CeedSetBackendFunction(ceed, "Operator", op, "Apply", 398fe2413ffSjeremylt CeedOperatorApply_Ref); CeedChk(ierr); 399fe2413ffSjeremylt ierr = CeedSetBackendFunction(ceed, "Operator", op, "Destroy", 400fe2413ffSjeremylt CeedOperatorDestroy_Ref); CeedChk(ierr); 40121617c04Sjeremylt return 0; 40221617c04Sjeremylt } 403