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 "ceed-ref.h" 1821617c04Sjeremylt 1921617c04Sjeremylt static int CeedOperatorDestroy_Ref(CeedOperator op) { 2021617c04Sjeremylt int ierr; 214ce2993fSjeremylt CeedOperator_Ref *impl; 224ce2993fSjeremylt ierr = CeedOperatorGetData(op, (void *)&impl); CeedChk(ierr); 2321617c04Sjeremylt 24885ac19cSjeremylt for (CeedInt i=0; i<impl->numein+impl->numeout; i++) { 25885ac19cSjeremylt ierr = CeedVectorDestroy(&impl->evecs[i]); CeedChk(ierr); 26885ac19cSjeremylt } 27885ac19cSjeremylt ierr = CeedFree(&impl->evecs); CeedChk(ierr); 28885ac19cSjeremylt ierr = CeedFree(&impl->edata); CeedChk(ierr); 298d713cf6Sjeremylt ierr = CeedFree(&impl->inputstate); CeedChk(ierr); 30885ac19cSjeremylt 31aedaa0e5Sjeremylt for (CeedInt i=0; i<impl->numein; i++) { 3291703d3fSjeremylt ierr = CeedVectorDestroy(&impl->evecsin[i]); CeedChk(ierr); 33aedaa0e5Sjeremylt ierr = CeedVectorDestroy(&impl->qvecsin[i]); CeedChk(ierr); 34885ac19cSjeremylt } 3591703d3fSjeremylt ierr = CeedFree(&impl->evecsin); CeedChk(ierr); 36aedaa0e5Sjeremylt ierr = CeedFree(&impl->qvecsin); CeedChk(ierr); 37885ac19cSjeremylt 38aedaa0e5Sjeremylt for (CeedInt i=0; i<impl->numeout; i++) { 3991703d3fSjeremylt ierr = CeedVectorDestroy(&impl->evecsout[i]); CeedChk(ierr); 40aedaa0e5Sjeremylt ierr = CeedVectorDestroy(&impl->qvecsout[i]); CeedChk(ierr); 41aedaa0e5Sjeremylt } 4291703d3fSjeremylt ierr = CeedFree(&impl->evecsout); CeedChk(ierr); 43aedaa0e5Sjeremylt ierr = CeedFree(&impl->qvecsout); CeedChk(ierr); 44885ac19cSjeremylt 45fe2413ffSjeremylt ierr = CeedFree(&impl); CeedChk(ierr); 4621617c04Sjeremylt return 0; 4721617c04Sjeremylt } 4821617c04Sjeremylt 49885ac19cSjeremylt /* 50885ac19cSjeremylt Setup infields or outfields 51885ac19cSjeremylt */ 52fe2413ffSjeremylt static int CeedOperatorSetupFields_Ref(CeedQFunction qf, CeedOperator op, 5391703d3fSjeremylt bool inOrOut, 5491703d3fSjeremylt CeedVector *fullevecs, CeedVector *evecs, 55aedaa0e5Sjeremylt CeedVector *qvecs, CeedInt starte, 56135a076eSjeremylt CeedInt numfields, CeedInt Q) { 574d537eeaSYohann CeedInt dim, ierr, size, P; 58aedaa0e5Sjeremylt Ceed ceed; 59aedaa0e5Sjeremylt ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 60d1bcdac9Sjeremylt CeedBasis basis; 61d1bcdac9Sjeremylt CeedElemRestriction Erestrict; 62aedaa0e5Sjeremylt CeedOperatorField *opfields; 63aedaa0e5Sjeremylt CeedQFunctionField *qffields; 64fe2413ffSjeremylt if (inOrOut) { 65aedaa0e5Sjeremylt ierr = CeedOperatorGetFields(op, NULL, &opfields); 66fe2413ffSjeremylt CeedChk(ierr); 67aedaa0e5Sjeremylt ierr = CeedQFunctionGetFields(qf, NULL, &qffields); 68fe2413ffSjeremylt CeedChk(ierr); 69fe2413ffSjeremylt } else { 70aedaa0e5Sjeremylt ierr = CeedOperatorGetFields(op, &opfields, NULL); 71fe2413ffSjeremylt CeedChk(ierr); 72aedaa0e5Sjeremylt ierr = CeedQFunctionGetFields(qf, &qffields, NULL); 73fe2413ffSjeremylt CeedChk(ierr); 74fe2413ffSjeremylt } 7521617c04Sjeremylt 76885ac19cSjeremylt // Loop over fields 77885ac19cSjeremylt for (CeedInt i=0; i<numfields; i++) { 78d1bcdac9Sjeremylt CeedEvalMode emode; 79aedaa0e5Sjeremylt ierr = CeedQFunctionFieldGetEvalMode(qffields[i], &emode); CeedChk(ierr); 80135a076eSjeremylt 81135a076eSjeremylt if (emode != CEED_EVAL_WEIGHT) { 82aedaa0e5Sjeremylt ierr = CeedOperatorFieldGetElemRestriction(opfields[i], &Erestrict); 83d1bcdac9Sjeremylt CeedChk(ierr); 84d1bcdac9Sjeremylt ierr = CeedElemRestrictionCreateVector(Erestrict, NULL, 8591703d3fSjeremylt &fullevecs[i+starte]); 86135a076eSjeremylt CeedChk(ierr); 87135a076eSjeremylt } 88135a076eSjeremylt 89885ac19cSjeremylt switch(emode) { 90885ac19cSjeremylt case CEED_EVAL_NONE: 914d537eeaSYohann ierr = CeedQFunctionFieldGetSize(qffields[i], &size); CeedChk(ierr); 924d537eeaSYohann ierr = CeedVectorCreate(ceed, Q*size, &qvecs[i]); CeedChk(ierr); 93aedaa0e5Sjeremylt break; 94aedaa0e5Sjeremylt case CEED_EVAL_INTERP: 954d537eeaSYohann ierr = CeedQFunctionFieldGetSize(qffields[i], &size); CeedChk(ierr); 964d1cd9fcSJeremy L Thompson ierr = CeedElemRestrictionGetElementSize(Erestrict, &P); 974d1cd9fcSJeremy L Thompson CeedChk(ierr); 984d537eeaSYohann ierr = CeedVectorCreate(ceed, P*size, &evecs[i]); CeedChk(ierr); 994d537eeaSYohann ierr = CeedVectorCreate(ceed, Q*size, &qvecs[i]); CeedChk(ierr); 100885ac19cSjeremylt break; 101885ac19cSjeremylt case CEED_EVAL_GRAD: 102aedaa0e5Sjeremylt ierr = CeedOperatorFieldGetBasis(opfields[i], &basis); CeedChk(ierr); 1034d537eeaSYohann ierr = CeedQFunctionFieldGetSize(qffields[i], &size); CeedChk(ierr); 104d1bcdac9Sjeremylt ierr = CeedBasisGetDimension(basis, &dim); CeedChk(ierr); 1054d1cd9fcSJeremy L Thompson ierr = CeedElemRestrictionGetElementSize(Erestrict, &P); 1064d1cd9fcSJeremy L Thompson CeedChk(ierr); 1074d537eeaSYohann ierr = CeedVectorCreate(ceed, P*size/dim, &evecs[i]); CeedChk(ierr); 1084d537eeaSYohann ierr = CeedVectorCreate(ceed, Q*size, &qvecs[i]); CeedChk(ierr); 109885ac19cSjeremylt break; 110885ac19cSjeremylt case CEED_EVAL_WEIGHT: // Only on input fields 111aedaa0e5Sjeremylt ierr = CeedOperatorFieldGetBasis(opfields[i], &basis); CeedChk(ierr); 112aedaa0e5Sjeremylt ierr = CeedVectorCreate(ceed, Q, &qvecs[i]); CeedChk(ierr); 113d1bcdac9Sjeremylt ierr = CeedBasisApply(basis, 1, CEED_NOTRANSPOSE, CEED_EVAL_WEIGHT, 114aedaa0e5Sjeremylt NULL, qvecs[i]); CeedChk(ierr); 115885ac19cSjeremylt break; 116885ac19cSjeremylt case CEED_EVAL_DIV: 1174d537eeaSYohann break; // Not implemented 118885ac19cSjeremylt case CEED_EVAL_CURL: 1194d537eeaSYohann break; // Not implemented 12021617c04Sjeremylt } 121885ac19cSjeremylt } 12221617c04Sjeremylt return 0; 12321617c04Sjeremylt } 12421617c04Sjeremylt 125885ac19cSjeremylt /* 126885ac19cSjeremylt CeedOperator needs to connect all the named fields (be they active or passive) 127885ac19cSjeremylt to the named inputs and outputs of its CeedQFunction. 128885ac19cSjeremylt */ 129885ac19cSjeremylt static int CeedOperatorSetup_Ref(CeedOperator op) { 13021617c04Sjeremylt int ierr; 1314ce2993fSjeremylt bool setupdone; 1324ce2993fSjeremylt ierr = CeedOperatorGetSetupStatus(op, &setupdone); CeedChk(ierr); 1334ce2993fSjeremylt if (setupdone) return 0; 134aedaa0e5Sjeremylt Ceed ceed; 135aedaa0e5Sjeremylt ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 1364ce2993fSjeremylt CeedOperator_Ref *impl; 1374ce2993fSjeremylt ierr = CeedOperatorGetData(op, (void *)&impl); CeedChk(ierr); 1384ce2993fSjeremylt CeedQFunction qf; 1394ce2993fSjeremylt ierr = CeedOperatorGetQFunction(op, &qf); CeedChk(ierr); 1404ce2993fSjeremylt CeedInt Q, numinputfields, numoutputfields; 1414ce2993fSjeremylt ierr = CeedOperatorGetNumQuadraturePoints(op, &Q); CeedChk(ierr); 142a8de75f0Sjeremylt ierr = CeedQFunctionGetNumArgs(qf, &numinputfields, &numoutputfields); 143a8de75f0Sjeremylt CeedChk(ierr); 144d1bcdac9Sjeremylt CeedOperatorField *opinputfields, *opoutputfields; 145d1bcdac9Sjeremylt ierr = CeedOperatorGetFields(op, &opinputfields, &opoutputfields); 146d1bcdac9Sjeremylt CeedChk(ierr); 147d1bcdac9Sjeremylt CeedQFunctionField *qfinputfields, *qfoutputfields; 148d1bcdac9Sjeremylt ierr = CeedQFunctionGetFields(qf, &qfinputfields, &qfoutputfields); 149d1bcdac9Sjeremylt CeedChk(ierr); 150885ac19cSjeremylt 151885ac19cSjeremylt // Allocate 152aedaa0e5Sjeremylt ierr = CeedCalloc(numinputfields + numoutputfields, &impl->evecs); 153aedaa0e5Sjeremylt CeedChk(ierr); 154aedaa0e5Sjeremylt ierr = CeedCalloc(numinputfields + numoutputfields, &impl->edata); 155885ac19cSjeremylt CeedChk(ierr); 156885ac19cSjeremylt 1578d713cf6Sjeremylt ierr = CeedCalloc(16, &impl->inputstate); CeedChk(ierr); 15891703d3fSjeremylt ierr = CeedCalloc(16, &impl->evecsin); CeedChk(ierr); 15991703d3fSjeremylt ierr = CeedCalloc(16, &impl->evecsout); CeedChk(ierr); 160aedaa0e5Sjeremylt ierr = CeedCalloc(16, &impl->qvecsin); CeedChk(ierr); 161aedaa0e5Sjeremylt ierr = CeedCalloc(16, &impl->qvecsout); CeedChk(ierr); 162885ac19cSjeremylt 163aedaa0e5Sjeremylt impl->numein = numinputfields; impl->numeout = numoutputfields; 164885ac19cSjeremylt 165aedaa0e5Sjeremylt // Set up infield and outfield evecs and qvecs 166885ac19cSjeremylt // Infields 16791703d3fSjeremylt ierr = CeedOperatorSetupFields_Ref(qf, op, 0, impl->evecs, 16891703d3fSjeremylt impl->evecsin, impl->qvecsin, 0, 169aedaa0e5Sjeremylt numinputfields, Q); 170aedaa0e5Sjeremylt CeedChk(ierr); 171885ac19cSjeremylt 172885ac19cSjeremylt // Outfields 17391703d3fSjeremylt ierr = CeedOperatorSetupFields_Ref(qf, op, 1, impl->evecs, 17491703d3fSjeremylt impl->evecsout, impl->qvecsout, 175aedaa0e5Sjeremylt numinputfields, numoutputfields, Q); 176d1bcdac9Sjeremylt CeedChk(ierr); 177885ac19cSjeremylt 1784ce2993fSjeremylt ierr = CeedOperatorSetSetupDone(op); CeedChk(ierr); 179885ac19cSjeremylt 180885ac19cSjeremylt return 0; 181885ac19cSjeremylt } 182885ac19cSjeremylt 183*1d102b48SJeremy L Thompson // Setup Input fields 184*1d102b48SJeremy L Thompson static inline int CeedOperatorSetupInputs_Ref(CeedInt numinputfields, 185*1d102b48SJeremy L Thompson CeedQFunctionField *qfinputfields, CeedOperatorField *opinputfields, 186*1d102b48SJeremy L Thompson CeedVector invec, const bool skipactive, CeedOperator_Ref *impl, 187*1d102b48SJeremy L Thompson CeedRequest *request) { 188*1d102b48SJeremy L Thompson CeedInt ierr; 189d1bcdac9Sjeremylt CeedEvalMode emode; 190d1bcdac9Sjeremylt CeedVector vec; 191d1bcdac9Sjeremylt CeedElemRestriction Erestrict; 192*1d102b48SJeremy L Thompson CeedTransposeMode lmode; 1938d713cf6Sjeremylt uint64_t state; 194885ac19cSjeremylt 1951a4ead9bSjeremylt for (CeedInt i=0; i<numinputfields; i++) { 196d1bcdac9Sjeremylt // Get input vector 197d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetVector(opinputfields[i], &vec); CeedChk(ierr); 198*1d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 199*1d102b48SJeremy L Thompson if (skipactive) 200*1d102b48SJeremy L Thompson continue; 201*1d102b48SJeremy L Thompson else 202d1bcdac9Sjeremylt vec = invec; 203*1d102b48SJeremy L Thompson } 204*1d102b48SJeremy L Thompson 205*1d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetEvalMode(qfinputfields[i], &emode); 206*1d102b48SJeremy L Thompson CeedChk(ierr); 207*1d102b48SJeremy L Thompson // Restrict and Evec 208*1d102b48SJeremy L Thompson if (emode == CEED_EVAL_WEIGHT) { // Skip 209*1d102b48SJeremy L Thompson } else { 210668048e2SJed Brown // Restrict 2118d713cf6Sjeremylt ierr = CeedVectorGetState(vec, &state); CeedChk(ierr); 2128d713cf6Sjeremylt // Skip restriction if input is unchanged 2138d713cf6Sjeremylt if (state != impl->inputstate[i] || vec == invec) { 214d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetElemRestriction(opinputfields[i], &Erestrict); 215d1bcdac9Sjeremylt CeedChk(ierr); 216*1d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetLMode(opinputfields[i], &lmode); 217*1d102b48SJeremy L Thompson CeedChk(ierr); 218d1bcdac9Sjeremylt ierr = CeedElemRestrictionApply(Erestrict, CEED_NOTRANSPOSE, 219d1bcdac9Sjeremylt lmode, vec, impl->evecs[i], 220668048e2SJed Brown request); CeedChk(ierr); 2218d713cf6Sjeremylt impl->inputstate[i] = state; 2228d713cf6Sjeremylt } 223668048e2SJed Brown // Get evec 224a2b73c81Sjeremylt ierr = CeedVectorGetArrayRead(impl->evecs[i], CEED_MEM_HOST, 225d1bcdac9Sjeremylt (const CeedScalar **) &impl->edata[i]); 226d1bcdac9Sjeremylt CeedChk(ierr); 227885ac19cSjeremylt } 228885ac19cSjeremylt } 229*1d102b48SJeremy L Thompson return 0; 230885ac19cSjeremylt } 231885ac19cSjeremylt 232*1d102b48SJeremy L Thompson // Input basis action 233*1d102b48SJeremy L Thompson static inline int CeedOperatorInputBasis_Ref(CeedInt e, CeedInt Q, 234*1d102b48SJeremy L Thompson CeedQFunctionField *qfinputfields, CeedOperatorField *opinputfields, 235*1d102b48SJeremy L Thompson CeedInt numinputfields, const bool skipactive, CeedOperator_Ref *impl) { 236*1d102b48SJeremy L Thompson CeedInt ierr; 237*1d102b48SJeremy L Thompson CeedInt dim, elemsize, size; 238*1d102b48SJeremy L Thompson CeedElemRestriction Erestrict; 239*1d102b48SJeremy L Thompson CeedEvalMode emode; 240*1d102b48SJeremy L Thompson CeedBasis basis; 241*1d102b48SJeremy L Thompson 2421a4ead9bSjeremylt for (CeedInt i=0; i<numinputfields; i++) { 243*1d102b48SJeremy L Thompson // Skip active input 244*1d102b48SJeremy L Thompson if (skipactive) { 245*1d102b48SJeremy L Thompson CeedVector vec; 246*1d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opinputfields[i], &vec); CeedChk(ierr); 247*1d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) 248*1d102b48SJeremy L Thompson continue; 249*1d102b48SJeremy L Thompson } 2504d537eeaSYohann // Get elemsize, emode, size 251d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetElemRestriction(opinputfields[i], &Erestrict); 252d1bcdac9Sjeremylt CeedChk(ierr); 253d1bcdac9Sjeremylt ierr = CeedElemRestrictionGetElementSize(Erestrict, &elemsize); 254d1bcdac9Sjeremylt CeedChk(ierr); 255d1bcdac9Sjeremylt ierr = CeedQFunctionFieldGetEvalMode(qfinputfields[i], &emode); 256d1bcdac9Sjeremylt CeedChk(ierr); 2574d537eeaSYohann ierr = CeedQFunctionFieldGetSize(qfinputfields[i], &size); CeedChk(ierr); 258885ac19cSjeremylt // Basis action 259885ac19cSjeremylt switch(emode) { 260885ac19cSjeremylt case CEED_EVAL_NONE: 261aedaa0e5Sjeremylt ierr = CeedVectorSetArray(impl->qvecsin[i], CEED_MEM_HOST, 262aedaa0e5Sjeremylt CEED_USE_POINTER, 2634d537eeaSYohann &impl->edata[i][e*Q*size]); CeedChk(ierr); 264885ac19cSjeremylt break; 265885ac19cSjeremylt case CEED_EVAL_INTERP: 266d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetBasis(opinputfields[i], &basis); CeedChk(ierr); 26791703d3fSjeremylt ierr = CeedVectorSetArray(impl->evecsin[i], CEED_MEM_HOST, 268aedaa0e5Sjeremylt CEED_USE_POINTER, 2694d537eeaSYohann &impl->edata[i][e*elemsize*size]); 270aedaa0e5Sjeremylt CeedChk(ierr); 271d1bcdac9Sjeremylt ierr = CeedBasisApply(basis, 1, CEED_NOTRANSPOSE, 27291703d3fSjeremylt CEED_EVAL_INTERP, impl->evecsin[i], 273aedaa0e5Sjeremylt impl->qvecsin[i]); CeedChk(ierr); 274885ac19cSjeremylt break; 275885ac19cSjeremylt case CEED_EVAL_GRAD: 276d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetBasis(opinputfields[i], &basis); CeedChk(ierr); 2774d537eeaSYohann ierr = CeedBasisGetDimension(basis, &dim); CeedChk(ierr); 27891703d3fSjeremylt ierr = CeedVectorSetArray(impl->evecsin[i], CEED_MEM_HOST, 279aedaa0e5Sjeremylt CEED_USE_POINTER, 2804d537eeaSYohann &impl->edata[i][e*elemsize*size/dim]); 281aedaa0e5Sjeremylt CeedChk(ierr); 282d1bcdac9Sjeremylt ierr = CeedBasisApply(basis, 1, CEED_NOTRANSPOSE, 28391703d3fSjeremylt CEED_EVAL_GRAD, impl->evecsin[i], 284aedaa0e5Sjeremylt impl->qvecsin[i]); CeedChk(ierr); 285885ac19cSjeremylt break; 286885ac19cSjeremylt case CEED_EVAL_WEIGHT: 287885ac19cSjeremylt break; // No action 288885ac19cSjeremylt case CEED_EVAL_DIV: 289*1d102b48SJeremy L Thompson case CEED_EVAL_CURL: { 290*1d102b48SJeremy L Thompson // LCOV_EXCL_START 291*1d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetBasis(opinputfields[i], &basis); 292*1d102b48SJeremy L Thompson CeedChk(ierr); 293*1d102b48SJeremy L Thompson Ceed ceed; 294*1d102b48SJeremy L Thompson ierr = CeedBasisGetCeed(basis, &ceed); CeedChk(ierr); 295*1d102b48SJeremy L Thompson return CeedError(ceed, 1, "Ceed evaluation mode not implemented"); 296*1d102b48SJeremy L Thompson // LCOV_EXCL_STOP 2974d537eeaSYohann break; // Not implemented 298885ac19cSjeremylt } 299885ac19cSjeremylt } 300885ac19cSjeremylt } 301*1d102b48SJeremy L Thompson return 0; 302885ac19cSjeremylt } 303885ac19cSjeremylt 304*1d102b48SJeremy L Thompson // Output basis action 305*1d102b48SJeremy L Thompson static inline int CeedOperatorOutputBasis_Ref(CeedInt e, CeedInt Q, 306*1d102b48SJeremy L Thompson CeedQFunctionField *qfoutputfields, CeedOperatorField *opoutputfields, 307*1d102b48SJeremy L Thompson CeedInt numinputfields, CeedInt numoutputfields, CeedOperator op, 308*1d102b48SJeremy L Thompson CeedOperator_Ref *impl) { 309*1d102b48SJeremy L Thompson CeedInt ierr; 310*1d102b48SJeremy L Thompson CeedInt dim, elemsize, size; 311*1d102b48SJeremy L Thompson CeedElemRestriction Erestrict; 312*1d102b48SJeremy L Thompson CeedEvalMode emode; 313*1d102b48SJeremy L Thompson CeedBasis basis; 314*1d102b48SJeremy L Thompson 3151a4ead9bSjeremylt for (CeedInt i=0; i<numoutputfields; i++) { 3164d537eeaSYohann // Get elemsize, emode, size 317d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetElemRestriction(opoutputfields[i], &Erestrict); 318d1bcdac9Sjeremylt CeedChk(ierr); 319d1bcdac9Sjeremylt ierr = CeedElemRestrictionGetElementSize(Erestrict, &elemsize); 320d1bcdac9Sjeremylt CeedChk(ierr); 321d1bcdac9Sjeremylt ierr = CeedQFunctionFieldGetEvalMode(qfoutputfields[i], &emode); 322d1bcdac9Sjeremylt CeedChk(ierr); 3234d537eeaSYohann ierr = CeedQFunctionFieldGetSize(qfoutputfields[i], &size); CeedChk(ierr); 324885ac19cSjeremylt // Basis action 325885ac19cSjeremylt switch(emode) { 326885ac19cSjeremylt case CEED_EVAL_NONE: 327885ac19cSjeremylt break; // No action 328885ac19cSjeremylt case CEED_EVAL_INTERP: 329d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetBasis(opoutputfields[i], &basis); 330d1bcdac9Sjeremylt CeedChk(ierr); 33191703d3fSjeremylt ierr = CeedVectorSetArray(impl->evecsout[i], CEED_MEM_HOST, 332aedaa0e5Sjeremylt CEED_USE_POINTER, 3334d537eeaSYohann &impl->edata[i + numinputfields][e*elemsize*size]); 334de686571SJeremy L Thompson CeedChk(ierr); 335aedaa0e5Sjeremylt ierr = CeedBasisApply(basis, 1, CEED_TRANSPOSE, 336aedaa0e5Sjeremylt CEED_EVAL_INTERP, impl->qvecsout[i], 33791703d3fSjeremylt impl->evecsout[i]); CeedChk(ierr); 338885ac19cSjeremylt break; 339885ac19cSjeremylt case CEED_EVAL_GRAD: 340d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetBasis(opoutputfields[i], &basis); 341d1bcdac9Sjeremylt CeedChk(ierr); 3424d537eeaSYohann ierr = CeedBasisGetDimension(basis, &dim); CeedChk(ierr); 34391703d3fSjeremylt ierr = CeedVectorSetArray(impl->evecsout[i], CEED_MEM_HOST, 344aedaa0e5Sjeremylt CEED_USE_POINTER, 3454d537eeaSYohann &impl->edata[i + numinputfields][e*elemsize*size/dim]); 346de686571SJeremy L Thompson CeedChk(ierr); 347aedaa0e5Sjeremylt ierr = CeedBasisApply(basis, 1, CEED_TRANSPOSE, 348aedaa0e5Sjeremylt CEED_EVAL_GRAD, impl->qvecsout[i], 34991703d3fSjeremylt impl->evecsout[i]); CeedChk(ierr); 350885ac19cSjeremylt break; 3514ce2993fSjeremylt case CEED_EVAL_WEIGHT: { 352c042f62fSJeremy L Thompson // LCOV_EXCL_START 3534ce2993fSjeremylt Ceed ceed; 3544ce2993fSjeremylt ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 355*1d102b48SJeremy L Thompson return CeedError(ceed, 1, "CEED_EVAL_WEIGHT cannot be an output " 356*1d102b48SJeremy L Thompson "evaluation mode"); 357c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 358885ac19cSjeremylt break; // Should not occur 3594ce2993fSjeremylt } 360885ac19cSjeremylt case CEED_EVAL_DIV: 361*1d102b48SJeremy L Thompson case CEED_EVAL_CURL: { 362*1d102b48SJeremy L Thompson // LCOV_EXCL_START 363*1d102b48SJeremy L Thompson Ceed ceed; 364*1d102b48SJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 365*1d102b48SJeremy L Thompson return CeedError(ceed, 1, "Ceed evaluation mode not implemented"); 366*1d102b48SJeremy L Thompson // LCOV_EXCL_STOP 3678c91a0c9SJeremy L Thompson break; // Not implemented 368885ac19cSjeremylt } 369885ac19cSjeremylt } 370885ac19cSjeremylt } 371*1d102b48SJeremy L Thompson return 0; 372*1d102b48SJeremy L Thompson } 373*1d102b48SJeremy L Thompson 374*1d102b48SJeremy L Thompson // Restore Inputs 375*1d102b48SJeremy L Thompson static inline int CeedOperatorRestoreInputs_Ref(CeedInt numinputfields, 376*1d102b48SJeremy L Thompson CeedQFunctionField *qfinputfields, CeedOperatorField *opinputfields, 377*1d102b48SJeremy L Thompson const bool skipactive, CeedOperator_Ref *impl) { 378*1d102b48SJeremy L Thompson CeedInt ierr; 379*1d102b48SJeremy L Thompson CeedEvalMode emode; 380*1d102b48SJeremy L Thompson 381*1d102b48SJeremy L Thompson for (CeedInt i=0; i<numinputfields; i++) { 382*1d102b48SJeremy L Thompson // Skip active inputs 383*1d102b48SJeremy L Thompson if (skipactive) { 384*1d102b48SJeremy L Thompson CeedVector vec; 385*1d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opinputfields[i], &vec); CeedChk(ierr); 386*1d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) 387*1d102b48SJeremy L Thompson continue; 388*1d102b48SJeremy L Thompson } 389*1d102b48SJeremy L Thompson // Restore input 390*1d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetEvalMode(qfinputfields[i], &emode); 391*1d102b48SJeremy L Thompson CeedChk(ierr); 392*1d102b48SJeremy L Thompson if (emode == CEED_EVAL_WEIGHT) { // Skip 393*1d102b48SJeremy L Thompson } else { 394*1d102b48SJeremy L Thompson ierr = CeedVectorRestoreArrayRead(impl->evecs[i], 395*1d102b48SJeremy L Thompson (const CeedScalar **) &impl->edata[i]); 396*1d102b48SJeremy L Thompson CeedChk(ierr); 397*1d102b48SJeremy L Thompson } 398*1d102b48SJeremy L Thompson } 399*1d102b48SJeremy L Thompson return 0; 400*1d102b48SJeremy L Thompson } 401*1d102b48SJeremy L Thompson 402*1d102b48SJeremy L Thompson // Apply Operator 403*1d102b48SJeremy L Thompson static int CeedOperatorApply_Ref(CeedOperator op, CeedVector invec, 404*1d102b48SJeremy L Thompson CeedVector outvec, CeedRequest *request) { 405*1d102b48SJeremy L Thompson int ierr; 406*1d102b48SJeremy L Thompson CeedOperator_Ref *impl; 407*1d102b48SJeremy L Thompson ierr = CeedOperatorGetData(op, (void *)&impl); CeedChk(ierr); 408*1d102b48SJeremy L Thompson CeedQFunction qf; 409*1d102b48SJeremy L Thompson ierr = CeedOperatorGetQFunction(op, &qf); CeedChk(ierr); 410*1d102b48SJeremy L Thompson CeedInt Q, numelements, numinputfields, numoutputfields, size; 411*1d102b48SJeremy L Thompson ierr = CeedOperatorGetNumQuadraturePoints(op, &Q); CeedChk(ierr); 412*1d102b48SJeremy L Thompson ierr = CeedOperatorGetNumElements(op, &numelements); CeedChk(ierr); 413*1d102b48SJeremy L Thompson ierr= CeedQFunctionGetNumArgs(qf, &numinputfields, &numoutputfields); 414*1d102b48SJeremy L Thompson CeedChk(ierr); 415*1d102b48SJeremy L Thompson CeedTransposeMode lmode; 416*1d102b48SJeremy L Thompson CeedOperatorField *opinputfields, *opoutputfields; 417*1d102b48SJeremy L Thompson ierr = CeedOperatorGetFields(op, &opinputfields, &opoutputfields); 418*1d102b48SJeremy L Thompson CeedChk(ierr); 419*1d102b48SJeremy L Thompson CeedQFunctionField *qfinputfields, *qfoutputfields; 420*1d102b48SJeremy L Thompson ierr = CeedQFunctionGetFields(qf, &qfinputfields, &qfoutputfields); 421*1d102b48SJeremy L Thompson CeedChk(ierr); 422*1d102b48SJeremy L Thompson CeedEvalMode emode; 423*1d102b48SJeremy L Thompson CeedVector vec; 424*1d102b48SJeremy L Thompson CeedElemRestriction Erestrict; 425*1d102b48SJeremy L Thompson 426*1d102b48SJeremy L Thompson // Setup 427*1d102b48SJeremy L Thompson ierr = CeedOperatorSetup_Ref(op); CeedChk(ierr); 428*1d102b48SJeremy L Thompson 429*1d102b48SJeremy L Thompson // Input Evecs and Restriction 430*1d102b48SJeremy L Thompson ierr = CeedOperatorSetupInputs_Ref(numinputfields, qfinputfields, 431*1d102b48SJeremy L Thompson opinputfields, invec, false, impl, 432*1d102b48SJeremy L Thompson request); CeedChk(ierr); 433*1d102b48SJeremy L Thompson 434*1d102b48SJeremy L Thompson // Output Evecs 435*1d102b48SJeremy L Thompson for (CeedInt i=0; i<numoutputfields; i++) { 436*1d102b48SJeremy L Thompson ierr = CeedVectorGetArray(impl->evecs[i+impl->numein], CEED_MEM_HOST, 437*1d102b48SJeremy L Thompson &impl->edata[i + numinputfields]); CeedChk(ierr); 438*1d102b48SJeremy L Thompson } 439*1d102b48SJeremy L Thompson 440*1d102b48SJeremy L Thompson // Loop through elements 441*1d102b48SJeremy L Thompson for (CeedInt e=0; e<numelements; e++) { 442*1d102b48SJeremy L Thompson // Input basis apply 443*1d102b48SJeremy L Thompson ierr = CeedOperatorInputBasis_Ref(e, Q, qfinputfields, opinputfields, 444*1d102b48SJeremy L Thompson numinputfields, false, impl); 445*1d102b48SJeremy L Thompson CeedChk(ierr); 446*1d102b48SJeremy L Thompson 447*1d102b48SJeremy L Thompson // Output pointers 448*1d102b48SJeremy L Thompson for (CeedInt i=0; i<numoutputfields; i++) { 449*1d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetEvalMode(qfoutputfields[i], &emode); 450*1d102b48SJeremy L Thompson CeedChk(ierr); 451*1d102b48SJeremy L Thompson if (emode == CEED_EVAL_NONE) { 452*1d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetSize(qfoutputfields[i], &size); 453*1d102b48SJeremy L Thompson CeedChk(ierr); 454*1d102b48SJeremy L Thompson ierr = CeedVectorSetArray(impl->qvecsout[i], CEED_MEM_HOST, 455*1d102b48SJeremy L Thompson CEED_USE_POINTER, 456*1d102b48SJeremy L Thompson &impl->edata[i + numinputfields][e*Q*size]); 457*1d102b48SJeremy L Thompson CeedChk(ierr); 458*1d102b48SJeremy L Thompson } 459*1d102b48SJeremy L Thompson } 460*1d102b48SJeremy L Thompson 461*1d102b48SJeremy L Thompson // Q function 462*1d102b48SJeremy L Thompson ierr = CeedQFunctionApply(qf, Q, impl->qvecsin, impl->qvecsout); CeedChk(ierr); 463*1d102b48SJeremy L Thompson 464*1d102b48SJeremy L Thompson // Output basis apply 465*1d102b48SJeremy L Thompson ierr = CeedOperatorOutputBasis_Ref(e, Q, qfoutputfields, opoutputfields, 466*1d102b48SJeremy L Thompson numinputfields, numoutputfields, op, impl); 467*1d102b48SJeremy L Thompson CeedChk(ierr); 468*1d102b48SJeremy L Thompson } 469885ac19cSjeremylt 47042ecf959Sjeremylt // Zero lvecs 471d1bcdac9Sjeremylt for (CeedInt i=0; i<numoutputfields; i++) { 472d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetVector(opoutputfields[i], &vec); CeedChk(ierr); 47352d6035fSJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 47452d6035fSJeremy L Thompson if (!impl->add) { 475d1bcdac9Sjeremylt vec = outvec; 476d1bcdac9Sjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 47742ecf959Sjeremylt } 47852d6035fSJeremy L Thompson } else { 47952d6035fSJeremy L Thompson ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 48052d6035fSJeremy L Thompson } 48152d6035fSJeremy L Thompson } 48252d6035fSJeremy L Thompson impl->add = false; 48342ecf959Sjeremylt 484885ac19cSjeremylt // Output restriction 4851a4ead9bSjeremylt for (CeedInt i=0; i<numoutputfields; i++) { 486a2b73c81Sjeremylt // Restore evec 487a2b73c81Sjeremylt ierr = CeedVectorRestoreArray(impl->evecs[i+impl->numein], 488d1bcdac9Sjeremylt &impl->edata[i + numinputfields]); 489d1bcdac9Sjeremylt CeedChk(ierr); 490d1bcdac9Sjeremylt // Get output vector 491d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetVector(opoutputfields[i], &vec); CeedChk(ierr); 492668048e2SJed Brown // Active 493d1bcdac9Sjeremylt if (vec == CEED_VECTOR_ACTIVE) 494d1bcdac9Sjeremylt vec = outvec; 4957ca8db16Sjeremylt // Restrict 496d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetElemRestriction(opoutputfields[i], &Erestrict); 497d1bcdac9Sjeremylt CeedChk(ierr); 4984dccadb6Sjeremylt ierr = CeedOperatorFieldGetLMode(opoutputfields[i], &lmode); CeedChk(ierr); 499d1bcdac9Sjeremylt ierr = CeedElemRestrictionApply(Erestrict, CEED_TRANSPOSE, 500d1bcdac9Sjeremylt lmode, impl->evecs[i+impl->numein], vec, 501668048e2SJed Brown request); CeedChk(ierr); 502885ac19cSjeremylt } 503885ac19cSjeremylt 5047ca8db16Sjeremylt // Restore input arrays 505*1d102b48SJeremy L Thompson ierr = CeedOperatorRestoreInputs_Ref(numinputfields, qfinputfields, 506*1d102b48SJeremy L Thompson opinputfields, false, impl); 507d1bcdac9Sjeremylt CeedChk(ierr); 5087ca8db16Sjeremylt 50921617c04Sjeremylt return 0; 51021617c04Sjeremylt } 51121617c04Sjeremylt 512*1d102b48SJeremy L Thompson // Composite operators 51352d6035fSJeremy L Thompson static int CeedCompositeOperatorApply_Ref(CeedOperator op, CeedVector invec, 51452d6035fSJeremy L Thompson CeedVector outvec, 51552d6035fSJeremy L Thompson CeedRequest *request) { 51652d6035fSJeremy L Thompson int ierr; 51752d6035fSJeremy L Thompson CeedInt numsub; 51852d6035fSJeremy L Thompson CeedOperator_Ref *impl; 51952d6035fSJeremy L Thompson CeedOperator *suboperators; 52052d6035fSJeremy L Thompson ierr = CeedOperatorGetNumSub(op, &numsub); CeedChk(ierr); 52152d6035fSJeremy L Thompson ierr = CeedOperatorGetSubList(op, &suboperators); CeedChk(ierr); 52252d6035fSJeremy L Thompson 52352d6035fSJeremy L Thompson // Overwrite outvec with first output 52452d6035fSJeremy L Thompson ierr = CeedOperatorApply(suboperators[0], invec, outvec, request); 52552d6035fSJeremy L Thompson CeedChk(ierr); 52652d6035fSJeremy L Thompson // Add to outvec with subsequent outputs 52752d6035fSJeremy L Thompson for (CeedInt i=1; i<numsub; i++) { 528de686571SJeremy L Thompson ierr = CeedOperatorGetData(suboperators[i], (void *)&impl); CeedChk(ierr); 52952d6035fSJeremy L Thompson impl->add = true; 53052d6035fSJeremy L Thompson ierr = CeedOperatorApply(suboperators[i], invec, outvec, request); 53152d6035fSJeremy L Thompson CeedChk(ierr); 53252d6035fSJeremy L Thompson } 53352d6035fSJeremy L Thompson 53452d6035fSJeremy L Thompson return 0; 53552d6035fSJeremy L Thompson } 53652d6035fSJeremy L Thompson 537*1d102b48SJeremy L Thompson // Assemble Linear QFunction 538*1d102b48SJeremy L Thompson static int CeedOperatorAssembleLinearQFunction_Ref(CeedOperator op, 539*1d102b48SJeremy L Thompson CeedVector *assembled, CeedElemRestriction *rstr, CeedRequest *request) { 540*1d102b48SJeremy L Thompson int ierr; 541*1d102b48SJeremy L Thompson CeedOperator_Ref *impl; 542*1d102b48SJeremy L Thompson ierr = CeedOperatorGetData(op, (void *)&impl); CeedChk(ierr); 543*1d102b48SJeremy L Thompson CeedQFunction qf; 544*1d102b48SJeremy L Thompson ierr = CeedOperatorGetQFunction(op, &qf); CeedChk(ierr); 545*1d102b48SJeremy L Thompson CeedInt Q, numelements, numinputfields, numoutputfields, size; 546*1d102b48SJeremy L Thompson ierr = CeedOperatorGetNumQuadraturePoints(op, &Q); CeedChk(ierr); 547*1d102b48SJeremy L Thompson ierr = CeedOperatorGetNumElements(op, &numelements); CeedChk(ierr); 548*1d102b48SJeremy L Thompson ierr= CeedQFunctionGetNumArgs(qf, &numinputfields, &numoutputfields); 549*1d102b48SJeremy L Thompson CeedChk(ierr); 550*1d102b48SJeremy L Thompson CeedOperatorField *opinputfields, *opoutputfields; 551*1d102b48SJeremy L Thompson ierr = CeedOperatorGetFields(op, &opinputfields, &opoutputfields); 552*1d102b48SJeremy L Thompson CeedChk(ierr); 553*1d102b48SJeremy L Thompson CeedQFunctionField *qfinputfields, *qfoutputfields; 554*1d102b48SJeremy L Thompson ierr = CeedQFunctionGetFields(qf, &qfinputfields, &qfoutputfields); 555*1d102b48SJeremy L Thompson CeedChk(ierr); 556*1d102b48SJeremy L Thompson CeedVector vec; 557*1d102b48SJeremy L Thompson CeedInt numactivein = 0, numactiveout = 0; 558*1d102b48SJeremy L Thompson CeedScalar **activein = NULL; 559*1d102b48SJeremy L Thompson CeedScalar *a, *tmp; 560*1d102b48SJeremy L Thompson Ceed ceed; 561*1d102b48SJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 562*1d102b48SJeremy L Thompson 563*1d102b48SJeremy L Thompson // Setup 564*1d102b48SJeremy L Thompson ierr = CeedOperatorSetup_Ref(op); CeedChk(ierr); 565*1d102b48SJeremy L Thompson 566*1d102b48SJeremy L Thompson // Input Evecs and Restriction 567*1d102b48SJeremy L Thompson ierr = CeedOperatorSetupInputs_Ref(numinputfields, qfinputfields, 568*1d102b48SJeremy L Thompson opinputfields, NULL, true, impl, request); CeedChk(ierr); 569*1d102b48SJeremy L Thompson 570*1d102b48SJeremy L Thompson // Count number of active input fields 571*1d102b48SJeremy L Thompson for (CeedInt i=0; i<numinputfields; i++) { 572*1d102b48SJeremy L Thompson // Get input vector 573*1d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opinputfields[i], &vec); CeedChk(ierr); 574*1d102b48SJeremy L Thompson // Check if active input 575*1d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 576*1d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetSize(qfinputfields[i], &size); CeedChk(ierr); 577*1d102b48SJeremy L Thompson ierr = CeedVectorSetValue(impl->qvecsin[i], 0.0); CeedChk(ierr); 578*1d102b48SJeremy L Thompson ierr = CeedVectorGetArray(impl->qvecsin[i], CEED_MEM_HOST, &tmp); 579*1d102b48SJeremy L Thompson CeedChk(ierr); 580*1d102b48SJeremy L Thompson ierr = CeedRealloc(numactivein + size, &activein); CeedChk(ierr); 581*1d102b48SJeremy L Thompson for (CeedInt field=0; field<size; field++) { 582*1d102b48SJeremy L Thompson activein[numactivein+field] = &tmp[field*Q]; 583*1d102b48SJeremy L Thompson } 584*1d102b48SJeremy L Thompson numactivein += size; 585*1d102b48SJeremy L Thompson ierr = CeedVectorRestoreArray(impl->qvecsin[i], &tmp); CeedChk(ierr); 586*1d102b48SJeremy L Thompson } 587*1d102b48SJeremy L Thompson } 588*1d102b48SJeremy L Thompson 589*1d102b48SJeremy L Thompson // Count number of active output fields 590*1d102b48SJeremy L Thompson for (CeedInt i=0; i<numoutputfields; i++) { 591*1d102b48SJeremy L Thompson // Get output vector 592*1d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opoutputfields[i], &vec); CeedChk(ierr); 593*1d102b48SJeremy L Thompson // Check if active output 594*1d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 595*1d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetSize(qfoutputfields[i], &size); CeedChk(ierr); 596*1d102b48SJeremy L Thompson numactiveout += size; 597*1d102b48SJeremy L Thompson } 598*1d102b48SJeremy L Thompson } 599*1d102b48SJeremy L Thompson 600*1d102b48SJeremy L Thompson // Check sizes 601*1d102b48SJeremy L Thompson if (!numactivein || !numactiveout) 602*1d102b48SJeremy L Thompson return CeedError(ceed, 1, 603*1d102b48SJeremy L Thompson "Cannot assemble QFunction without active inputs and outputs"); 604*1d102b48SJeremy L Thompson 605*1d102b48SJeremy L Thompson // Create output restriction 606*1d102b48SJeremy L Thompson ierr = CeedElemRestrictionCreateIdentity(ceed, numelements, Q, 607*1d102b48SJeremy L Thompson numelements*Q, 608*1d102b48SJeremy L Thompson numactivein*numactiveout, rstr); 609*1d102b48SJeremy L Thompson CeedChk(ierr); 610*1d102b48SJeremy L Thompson // Create assembled vector 611*1d102b48SJeremy L Thompson ierr = CeedVectorCreate(ceed, numelements*Q*numactivein*numactiveout, 612*1d102b48SJeremy L Thompson assembled); CeedChk(ierr); 613*1d102b48SJeremy L Thompson ierr = CeedVectorSetValue(*assembled, 0.0); CeedChk(ierr); 614*1d102b48SJeremy L Thompson ierr = CeedVectorGetArray(*assembled, CEED_MEM_HOST, &a); CeedChk(ierr); 615*1d102b48SJeremy L Thompson 616*1d102b48SJeremy L Thompson // Loop through elements 617*1d102b48SJeremy L Thompson for (CeedInt e=0; e<numelements; e++) { 618*1d102b48SJeremy L Thompson // Input basis apply 619*1d102b48SJeremy L Thompson ierr = CeedOperatorInputBasis_Ref(e, Q, qfinputfields, opinputfields, 620*1d102b48SJeremy L Thompson numinputfields, true, impl); 621*1d102b48SJeremy L Thompson CeedChk(ierr); 622*1d102b48SJeremy L Thompson 623*1d102b48SJeremy L Thompson // Assemble QFunction 624*1d102b48SJeremy L Thompson for (CeedInt in=0; in<numactivein; in++) { 625*1d102b48SJeremy L Thompson // Set Inputs 626*1d102b48SJeremy L Thompson for (CeedInt q=0; q<Q; q++) 627*1d102b48SJeremy L Thompson activein[in][q] = 1; 628*1d102b48SJeremy L Thompson if (numactivein > 1) 629*1d102b48SJeremy L Thompson for (CeedInt q=0; q<Q; q++) 630*1d102b48SJeremy L Thompson activein[(in+numactivein-1)%numactivein][q] = 0; 631*1d102b48SJeremy L Thompson // Set Outputs 632*1d102b48SJeremy L Thompson for (CeedInt out=0; out<numoutputfields; out++) { 633*1d102b48SJeremy L Thompson // Get output vector 634*1d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opoutputfields[out], &vec); 635*1d102b48SJeremy L Thompson CeedChk(ierr); 636*1d102b48SJeremy L Thompson // Check if active output 637*1d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 638*1d102b48SJeremy L Thompson CeedVectorSetArray(impl->qvecsout[out], CEED_MEM_HOST, 639*1d102b48SJeremy L Thompson CEED_USE_POINTER, a); CeedChk(ierr); 640*1d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetSize(qfoutputfields[out], &size); 641*1d102b48SJeremy L Thompson CeedChk(ierr); 642*1d102b48SJeremy L Thompson a += size*Q; // Advance the pointer by the size of the output 643*1d102b48SJeremy L Thompson } 644*1d102b48SJeremy L Thompson } 645*1d102b48SJeremy L Thompson // Apply QFunction 646*1d102b48SJeremy L Thompson ierr = CeedQFunctionApply(qf, Q, impl->qvecsin, impl->qvecsout); 647*1d102b48SJeremy L Thompson CeedChk(ierr); 648*1d102b48SJeremy L Thompson } 649*1d102b48SJeremy L Thompson } 650*1d102b48SJeremy L Thompson 651*1d102b48SJeremy L Thompson // Un-set output Qvecs to prevent accidental overwrite of Assembled 652*1d102b48SJeremy L Thompson for (CeedInt out=0; out<numoutputfields; out++) { 653*1d102b48SJeremy L Thompson // Get output vector 654*1d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opoutputfields[out], &vec); 655*1d102b48SJeremy L Thompson CeedChk(ierr); 656*1d102b48SJeremy L Thompson // Check if active output 657*1d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 658*1d102b48SJeremy L Thompson CeedVectorSetArray(impl->qvecsout[out], CEED_MEM_HOST, CEED_COPY_VALUES, 659*1d102b48SJeremy L Thompson NULL); CeedChk(ierr); 660*1d102b48SJeremy L Thompson } 661*1d102b48SJeremy L Thompson } 662*1d102b48SJeremy L Thompson 663*1d102b48SJeremy L Thompson // Restore input arrays 664*1d102b48SJeremy L Thompson ierr = CeedOperatorRestoreInputs_Ref(numinputfields, qfinputfields, 665*1d102b48SJeremy L Thompson opinputfields, true, impl); 666*1d102b48SJeremy L Thompson CeedChk(ierr); 667*1d102b48SJeremy L Thompson 668*1d102b48SJeremy L Thompson // Restore output 669*1d102b48SJeremy L Thompson ierr = CeedVectorRestoreArray(*assembled, &a); CeedChk(ierr); 670*1d102b48SJeremy L Thompson 671*1d102b48SJeremy L Thompson // Cleanup 672*1d102b48SJeremy L Thompson ierr = CeedFree(&activein); CeedChk(ierr); 673*1d102b48SJeremy L Thompson 674*1d102b48SJeremy L Thompson return 0; 675*1d102b48SJeremy L Thompson } 676*1d102b48SJeremy L Thompson 67721617c04Sjeremylt int CeedOperatorCreate_Ref(CeedOperator op) { 67821617c04Sjeremylt int ierr; 679fe2413ffSjeremylt Ceed ceed; 680fe2413ffSjeremylt ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 6814ce2993fSjeremylt CeedOperator_Ref *impl; 68221617c04Sjeremylt 68321617c04Sjeremylt ierr = CeedCalloc(1, &impl); CeedChk(ierr); 68452d6035fSJeremy L Thompson impl->add = false; 685de686571SJeremy L Thompson ierr = CeedOperatorSetData(op, (void *)&impl); CeedChk(ierr); 686fe2413ffSjeremylt 687*1d102b48SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Operator", op, "AssembleLinearQFunction", 688*1d102b48SJeremy L Thompson CeedOperatorAssembleLinearQFunction_Ref); 689*1d102b48SJeremy L Thompson CeedChk(ierr); 690fe2413ffSjeremylt ierr = CeedSetBackendFunction(ceed, "Operator", op, "Apply", 691fe2413ffSjeremylt CeedOperatorApply_Ref); CeedChk(ierr); 692fe2413ffSjeremylt ierr = CeedSetBackendFunction(ceed, "Operator", op, "Destroy", 693fe2413ffSjeremylt CeedOperatorDestroy_Ref); CeedChk(ierr); 69421617c04Sjeremylt return 0; 69521617c04Sjeremylt } 69652d6035fSJeremy L Thompson 69752d6035fSJeremy L Thompson int CeedCompositeOperatorCreate_Ref(CeedOperator op) { 69852d6035fSJeremy L Thompson int ierr; 69952d6035fSJeremy L Thompson Ceed ceed; 70052d6035fSJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 70152d6035fSJeremy L Thompson 70252d6035fSJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Operator", op, "Apply", 70352d6035fSJeremy L Thompson CeedCompositeOperatorApply_Ref); CeedChk(ierr); 70452d6035fSJeremy L Thompson return 0; 70552d6035fSJeremy L Thompson } 706