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 1831d102b48SJeremy L Thompson // Setup Input fields 1841d102b48SJeremy L Thompson static inline int CeedOperatorSetupInputs_Ref(CeedInt numinputfields, 1851d102b48SJeremy L Thompson CeedQFunctionField *qfinputfields, CeedOperatorField *opinputfields, 1861d102b48SJeremy L Thompson CeedVector invec, const bool skipactive, CeedOperator_Ref *impl, 1871d102b48SJeremy L Thompson CeedRequest *request) { 1881d102b48SJeremy L Thompson CeedInt ierr; 189d1bcdac9Sjeremylt CeedEvalMode emode; 190d1bcdac9Sjeremylt CeedVector vec; 191d1bcdac9Sjeremylt CeedElemRestriction Erestrict; 1921d102b48SJeremy 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); 1981d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 1991d102b48SJeremy L Thompson if (skipactive) 2001d102b48SJeremy L Thompson continue; 2011d102b48SJeremy L Thompson else 202d1bcdac9Sjeremylt vec = invec; 2031d102b48SJeremy L Thompson } 2041d102b48SJeremy L Thompson 2051d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetEvalMode(qfinputfields[i], &emode); 2061d102b48SJeremy L Thompson CeedChk(ierr); 2071d102b48SJeremy L Thompson // Restrict and Evec 2081d102b48SJeremy L Thompson if (emode == CEED_EVAL_WEIGHT) { // Skip 2091d102b48SJeremy 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); 2161d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetLMode(opinputfields[i], &lmode); 2171d102b48SJeremy 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 } 2291d102b48SJeremy L Thompson return 0; 230885ac19cSjeremylt } 231885ac19cSjeremylt 2321d102b48SJeremy L Thompson // Input basis action 2331d102b48SJeremy L Thompson static inline int CeedOperatorInputBasis_Ref(CeedInt e, CeedInt Q, 2341d102b48SJeremy L Thompson CeedQFunctionField *qfinputfields, CeedOperatorField *opinputfields, 2351d102b48SJeremy L Thompson CeedInt numinputfields, const bool skipactive, CeedOperator_Ref *impl) { 2361d102b48SJeremy L Thompson CeedInt ierr; 2371d102b48SJeremy L Thompson CeedInt dim, elemsize, size; 2381d102b48SJeremy L Thompson CeedElemRestriction Erestrict; 2391d102b48SJeremy L Thompson CeedEvalMode emode; 2401d102b48SJeremy L Thompson CeedBasis basis; 2411d102b48SJeremy L Thompson 2421a4ead9bSjeremylt for (CeedInt i=0; i<numinputfields; i++) { 2431d102b48SJeremy L Thompson // Skip active input 2441d102b48SJeremy L Thompson if (skipactive) { 2451d102b48SJeremy L Thompson CeedVector vec; 2461d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opinputfields[i], &vec); CeedChk(ierr); 2471d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) 2481d102b48SJeremy L Thompson continue; 2491d102b48SJeremy 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: 2891d102b48SJeremy L Thompson case CEED_EVAL_CURL: { 2901d102b48SJeremy L Thompson // LCOV_EXCL_START 2911d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetBasis(opinputfields[i], &basis); 2921d102b48SJeremy L Thompson CeedChk(ierr); 2931d102b48SJeremy L Thompson Ceed ceed; 2941d102b48SJeremy L Thompson ierr = CeedBasisGetCeed(basis, &ceed); CeedChk(ierr); 2951d102b48SJeremy L Thompson return CeedError(ceed, 1, "Ceed evaluation mode not implemented"); 2961d102b48SJeremy L Thompson // LCOV_EXCL_STOP 2974d537eeaSYohann break; // Not implemented 298885ac19cSjeremylt } 299885ac19cSjeremylt } 300885ac19cSjeremylt } 3011d102b48SJeremy L Thompson return 0; 302885ac19cSjeremylt } 303885ac19cSjeremylt 3041d102b48SJeremy L Thompson // Output basis action 3051d102b48SJeremy L Thompson static inline int CeedOperatorOutputBasis_Ref(CeedInt e, CeedInt Q, 3061d102b48SJeremy L Thompson CeedQFunctionField *qfoutputfields, CeedOperatorField *opoutputfields, 3071d102b48SJeremy L Thompson CeedInt numinputfields, CeedInt numoutputfields, CeedOperator op, 3081d102b48SJeremy L Thompson CeedOperator_Ref *impl) { 3091d102b48SJeremy L Thompson CeedInt ierr; 3101d102b48SJeremy L Thompson CeedInt dim, elemsize, size; 3111d102b48SJeremy L Thompson CeedElemRestriction Erestrict; 3121d102b48SJeremy L Thompson CeedEvalMode emode; 3131d102b48SJeremy L Thompson CeedBasis basis; 3141d102b48SJeremy 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); 3551d102b48SJeremy L Thompson return CeedError(ceed, 1, "CEED_EVAL_WEIGHT cannot be an output " 3561d102b48SJeremy L Thompson "evaluation mode"); 357c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 358885ac19cSjeremylt break; // Should not occur 3594ce2993fSjeremylt } 360885ac19cSjeremylt case CEED_EVAL_DIV: 3611d102b48SJeremy L Thompson case CEED_EVAL_CURL: { 3621d102b48SJeremy L Thompson // LCOV_EXCL_START 3631d102b48SJeremy L Thompson Ceed ceed; 3641d102b48SJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 3651d102b48SJeremy L Thompson return CeedError(ceed, 1, "Ceed evaluation mode not implemented"); 3661d102b48SJeremy L Thompson // LCOV_EXCL_STOP 3678c91a0c9SJeremy L Thompson break; // Not implemented 368885ac19cSjeremylt } 369885ac19cSjeremylt } 370885ac19cSjeremylt } 3711d102b48SJeremy L Thompson return 0; 3721d102b48SJeremy L Thompson } 3731d102b48SJeremy L Thompson 3741d102b48SJeremy L Thompson // Restore Inputs 3751d102b48SJeremy L Thompson static inline int CeedOperatorRestoreInputs_Ref(CeedInt numinputfields, 3761d102b48SJeremy L Thompson CeedQFunctionField *qfinputfields, CeedOperatorField *opinputfields, 3771d102b48SJeremy L Thompson const bool skipactive, CeedOperator_Ref *impl) { 3781d102b48SJeremy L Thompson CeedInt ierr; 3791d102b48SJeremy L Thompson CeedEvalMode emode; 3801d102b48SJeremy L Thompson 3811d102b48SJeremy L Thompson for (CeedInt i=0; i<numinputfields; i++) { 3821d102b48SJeremy L Thompson // Skip active inputs 3831d102b48SJeremy L Thompson if (skipactive) { 3841d102b48SJeremy L Thompson CeedVector vec; 3851d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opinputfields[i], &vec); CeedChk(ierr); 3861d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) 3871d102b48SJeremy L Thompson continue; 3881d102b48SJeremy L Thompson } 3891d102b48SJeremy L Thompson // Restore input 3901d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetEvalMode(qfinputfields[i], &emode); 3911d102b48SJeremy L Thompson CeedChk(ierr); 3921d102b48SJeremy L Thompson if (emode == CEED_EVAL_WEIGHT) { // Skip 3931d102b48SJeremy L Thompson } else { 3941d102b48SJeremy L Thompson ierr = CeedVectorRestoreArrayRead(impl->evecs[i], 3951d102b48SJeremy L Thompson (const CeedScalar **) &impl->edata[i]); 3961d102b48SJeremy L Thompson CeedChk(ierr); 3971d102b48SJeremy L Thompson } 3981d102b48SJeremy L Thompson } 3991d102b48SJeremy L Thompson return 0; 4001d102b48SJeremy L Thompson } 4011d102b48SJeremy L Thompson 4021d102b48SJeremy L Thompson // Apply Operator 4031d102b48SJeremy L Thompson static int CeedOperatorApply_Ref(CeedOperator op, CeedVector invec, 4041d102b48SJeremy L Thompson CeedVector outvec, CeedRequest *request) { 4051d102b48SJeremy L Thompson int ierr; 4061d102b48SJeremy L Thompson CeedOperator_Ref *impl; 4071d102b48SJeremy L Thompson ierr = CeedOperatorGetData(op, (void *)&impl); CeedChk(ierr); 4081d102b48SJeremy L Thompson CeedQFunction qf; 4091d102b48SJeremy L Thompson ierr = CeedOperatorGetQFunction(op, &qf); CeedChk(ierr); 4101d102b48SJeremy L Thompson CeedInt Q, numelements, numinputfields, numoutputfields, size; 4111d102b48SJeremy L Thompson ierr = CeedOperatorGetNumQuadraturePoints(op, &Q); CeedChk(ierr); 4121d102b48SJeremy L Thompson ierr = CeedOperatorGetNumElements(op, &numelements); CeedChk(ierr); 4131d102b48SJeremy L Thompson ierr= CeedQFunctionGetNumArgs(qf, &numinputfields, &numoutputfields); 4141d102b48SJeremy L Thompson CeedChk(ierr); 4151d102b48SJeremy L Thompson CeedTransposeMode lmode; 4161d102b48SJeremy L Thompson CeedOperatorField *opinputfields, *opoutputfields; 4171d102b48SJeremy L Thompson ierr = CeedOperatorGetFields(op, &opinputfields, &opoutputfields); 4181d102b48SJeremy L Thompson CeedChk(ierr); 4191d102b48SJeremy L Thompson CeedQFunctionField *qfinputfields, *qfoutputfields; 4201d102b48SJeremy L Thompson ierr = CeedQFunctionGetFields(qf, &qfinputfields, &qfoutputfields); 4211d102b48SJeremy L Thompson CeedChk(ierr); 4221d102b48SJeremy L Thompson CeedEvalMode emode; 4231d102b48SJeremy L Thompson CeedVector vec; 4241d102b48SJeremy L Thompson CeedElemRestriction Erestrict; 4251d102b48SJeremy L Thompson 4261d102b48SJeremy L Thompson // Setup 4271d102b48SJeremy L Thompson ierr = CeedOperatorSetup_Ref(op); CeedChk(ierr); 4281d102b48SJeremy L Thompson 4291d102b48SJeremy L Thompson // Input Evecs and Restriction 4301d102b48SJeremy L Thompson ierr = CeedOperatorSetupInputs_Ref(numinputfields, qfinputfields, 4311d102b48SJeremy L Thompson opinputfields, invec, false, impl, 4321d102b48SJeremy L Thompson request); CeedChk(ierr); 4331d102b48SJeremy L Thompson 4341d102b48SJeremy L Thompson // Output Evecs 4351d102b48SJeremy L Thompson for (CeedInt i=0; i<numoutputfields; i++) { 4361d102b48SJeremy L Thompson ierr = CeedVectorGetArray(impl->evecs[i+impl->numein], CEED_MEM_HOST, 4371d102b48SJeremy L Thompson &impl->edata[i + numinputfields]); CeedChk(ierr); 4381d102b48SJeremy L Thompson } 4391d102b48SJeremy L Thompson 4401d102b48SJeremy L Thompson // Loop through elements 4411d102b48SJeremy L Thompson for (CeedInt e=0; e<numelements; e++) { 4421d102b48SJeremy L Thompson // Input basis apply 4431d102b48SJeremy L Thompson ierr = CeedOperatorInputBasis_Ref(e, Q, qfinputfields, opinputfields, 4441d102b48SJeremy L Thompson numinputfields, false, impl); 4451d102b48SJeremy L Thompson CeedChk(ierr); 4461d102b48SJeremy L Thompson 4471d102b48SJeremy L Thompson // Output pointers 4481d102b48SJeremy L Thompson for (CeedInt i=0; i<numoutputfields; i++) { 4491d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetEvalMode(qfoutputfields[i], &emode); 4501d102b48SJeremy L Thompson CeedChk(ierr); 4511d102b48SJeremy L Thompson if (emode == CEED_EVAL_NONE) { 4521d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetSize(qfoutputfields[i], &size); 4531d102b48SJeremy L Thompson CeedChk(ierr); 4541d102b48SJeremy L Thompson ierr = CeedVectorSetArray(impl->qvecsout[i], CEED_MEM_HOST, 4551d102b48SJeremy L Thompson CEED_USE_POINTER, 4561d102b48SJeremy L Thompson &impl->edata[i + numinputfields][e*Q*size]); 4571d102b48SJeremy L Thompson CeedChk(ierr); 4581d102b48SJeremy L Thompson } 4591d102b48SJeremy L Thompson } 4601d102b48SJeremy L Thompson 4611d102b48SJeremy L Thompson // Q function 4621d102b48SJeremy L Thompson ierr = CeedQFunctionApply(qf, Q, impl->qvecsin, impl->qvecsout); CeedChk(ierr); 4631d102b48SJeremy L Thompson 4641d102b48SJeremy L Thompson // Output basis apply 4651d102b48SJeremy L Thompson ierr = CeedOperatorOutputBasis_Ref(e, Q, qfoutputfields, opoutputfields, 4661d102b48SJeremy L Thompson numinputfields, numoutputfields, op, impl); 4671d102b48SJeremy L Thompson CeedChk(ierr); 4681d102b48SJeremy 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 5051d102b48SJeremy L Thompson ierr = CeedOperatorRestoreInputs_Ref(numinputfields, qfinputfields, 5061d102b48SJeremy L Thompson opinputfields, false, impl); 507d1bcdac9Sjeremylt CeedChk(ierr); 5087ca8db16Sjeremylt 50921617c04Sjeremylt return 0; 51021617c04Sjeremylt } 51121617c04Sjeremylt 5121d102b48SJeremy 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 5371d102b48SJeremy L Thompson // Assemble Linear QFunction 5381d102b48SJeremy L Thompson static int CeedOperatorAssembleLinearQFunction_Ref(CeedOperator op, 5391d102b48SJeremy L Thompson CeedVector *assembled, CeedElemRestriction *rstr, CeedRequest *request) { 5401d102b48SJeremy L Thompson int ierr; 5411d102b48SJeremy L Thompson CeedOperator_Ref *impl; 5421d102b48SJeremy L Thompson ierr = CeedOperatorGetData(op, (void *)&impl); CeedChk(ierr); 5431d102b48SJeremy L Thompson CeedQFunction qf; 5441d102b48SJeremy L Thompson ierr = CeedOperatorGetQFunction(op, &qf); CeedChk(ierr); 5451d102b48SJeremy L Thompson CeedInt Q, numelements, numinputfields, numoutputfields, size; 5461d102b48SJeremy L Thompson ierr = CeedOperatorGetNumQuadraturePoints(op, &Q); CeedChk(ierr); 5471d102b48SJeremy L Thompson ierr = CeedOperatorGetNumElements(op, &numelements); CeedChk(ierr); 5481d102b48SJeremy L Thompson ierr= CeedQFunctionGetNumArgs(qf, &numinputfields, &numoutputfields); 5491d102b48SJeremy L Thompson CeedChk(ierr); 5501d102b48SJeremy L Thompson CeedOperatorField *opinputfields, *opoutputfields; 5511d102b48SJeremy L Thompson ierr = CeedOperatorGetFields(op, &opinputfields, &opoutputfields); 5521d102b48SJeremy L Thompson CeedChk(ierr); 5531d102b48SJeremy L Thompson CeedQFunctionField *qfinputfields, *qfoutputfields; 5541d102b48SJeremy L Thompson ierr = CeedQFunctionGetFields(qf, &qfinputfields, &qfoutputfields); 5551d102b48SJeremy L Thompson CeedChk(ierr); 5561d102b48SJeremy L Thompson CeedVector vec; 5571d102b48SJeremy L Thompson CeedInt numactivein = 0, numactiveout = 0; 558*42ea3801Sjeremylt CeedVector *activein = NULL; 5591d102b48SJeremy L Thompson CeedScalar *a, *tmp; 5601d102b48SJeremy L Thompson Ceed ceed; 5611d102b48SJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 5621d102b48SJeremy L Thompson 5631d102b48SJeremy L Thompson // Setup 5641d102b48SJeremy L Thompson ierr = CeedOperatorSetup_Ref(op); CeedChk(ierr); 5651d102b48SJeremy L Thompson 5661d102b48SJeremy L Thompson // Input Evecs and Restriction 5671d102b48SJeremy L Thompson ierr = CeedOperatorSetupInputs_Ref(numinputfields, qfinputfields, 5681d102b48SJeremy L Thompson opinputfields, NULL, true, impl, request); CeedChk(ierr); 5691d102b48SJeremy L Thompson 5701d102b48SJeremy L Thompson // Count number of active input fields 5711d102b48SJeremy L Thompson for (CeedInt i=0; i<numinputfields; i++) { 5721d102b48SJeremy L Thompson // Get input vector 5731d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opinputfields[i], &vec); CeedChk(ierr); 5741d102b48SJeremy L Thompson // Check if active input 5751d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 5761d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetSize(qfinputfields[i], &size); CeedChk(ierr); 5771d102b48SJeremy L Thompson ierr = CeedVectorSetValue(impl->qvecsin[i], 0.0); CeedChk(ierr); 5781d102b48SJeremy L Thompson ierr = CeedVectorGetArray(impl->qvecsin[i], CEED_MEM_HOST, &tmp); 5791d102b48SJeremy L Thompson CeedChk(ierr); 5801d102b48SJeremy L Thompson ierr = CeedRealloc(numactivein + size, &activein); CeedChk(ierr); 5811d102b48SJeremy L Thompson for (CeedInt field=0; field<size; field++) { 582*42ea3801Sjeremylt ierr = CeedVectorCreate(ceed, Q, &activein[numactivein+field]); 583*42ea3801Sjeremylt CeedChk(ierr); 584*42ea3801Sjeremylt ierr = CeedVectorSetArray(activein[numactivein+field], CEED_MEM_HOST, 585*42ea3801Sjeremylt CEED_USE_POINTER, &tmp[field*Q]); 5861d102b48SJeremy L Thompson } 5871d102b48SJeremy L Thompson numactivein += size; 5881d102b48SJeremy L Thompson ierr = CeedVectorRestoreArray(impl->qvecsin[i], &tmp); CeedChk(ierr); 5891d102b48SJeremy L Thompson } 5901d102b48SJeremy L Thompson } 5911d102b48SJeremy L Thompson 5921d102b48SJeremy L Thompson // Count number of active output fields 5931d102b48SJeremy L Thompson for (CeedInt i=0; i<numoutputfields; i++) { 5941d102b48SJeremy L Thompson // Get output vector 5951d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opoutputfields[i], &vec); CeedChk(ierr); 5961d102b48SJeremy L Thompson // Check if active output 5971d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 5981d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetSize(qfoutputfields[i], &size); CeedChk(ierr); 5991d102b48SJeremy L Thompson numactiveout += size; 6001d102b48SJeremy L Thompson } 6011d102b48SJeremy L Thompson } 6021d102b48SJeremy L Thompson 6031d102b48SJeremy L Thompson // Check sizes 6041d102b48SJeremy L Thompson if (!numactivein || !numactiveout) 6051d102b48SJeremy L Thompson return CeedError(ceed, 1, 6061d102b48SJeremy L Thompson "Cannot assemble QFunction without active inputs and outputs"); 6071d102b48SJeremy L Thompson 6081d102b48SJeremy L Thompson // Create output restriction 6091d102b48SJeremy L Thompson ierr = CeedElemRestrictionCreateIdentity(ceed, numelements, Q, 6101d102b48SJeremy L Thompson numelements*Q, 6111d102b48SJeremy L Thompson numactivein*numactiveout, rstr); 6121d102b48SJeremy L Thompson CeedChk(ierr); 6131d102b48SJeremy L Thompson // Create assembled vector 6141d102b48SJeremy L Thompson ierr = CeedVectorCreate(ceed, numelements*Q*numactivein*numactiveout, 6151d102b48SJeremy L Thompson assembled); CeedChk(ierr); 6161d102b48SJeremy L Thompson ierr = CeedVectorSetValue(*assembled, 0.0); CeedChk(ierr); 6171d102b48SJeremy L Thompson ierr = CeedVectorGetArray(*assembled, CEED_MEM_HOST, &a); CeedChk(ierr); 6181d102b48SJeremy L Thompson 6191d102b48SJeremy L Thompson // Loop through elements 6201d102b48SJeremy L Thompson for (CeedInt e=0; e<numelements; e++) { 6211d102b48SJeremy L Thompson // Input basis apply 6221d102b48SJeremy L Thompson ierr = CeedOperatorInputBasis_Ref(e, Q, qfinputfields, opinputfields, 6231d102b48SJeremy L Thompson numinputfields, true, impl); 6241d102b48SJeremy L Thompson CeedChk(ierr); 6251d102b48SJeremy L Thompson 6261d102b48SJeremy L Thompson // Assemble QFunction 6271d102b48SJeremy L Thompson for (CeedInt in=0; in<numactivein; in++) { 6281d102b48SJeremy L Thompson // Set Inputs 629*42ea3801Sjeremylt ierr = CeedVectorSetValue(activein[in], 1.0); CeedChk(ierr); 630*42ea3801Sjeremylt if (numactivein > 1) { 631*42ea3801Sjeremylt ierr = CeedVectorSetValue(activein[(in+numactivein-1)%numactivein], 632*42ea3801Sjeremylt 0.0); CeedChk(ierr); 633*42ea3801Sjeremylt } 6341d102b48SJeremy L Thompson // Set Outputs 6351d102b48SJeremy L Thompson for (CeedInt out=0; out<numoutputfields; out++) { 6361d102b48SJeremy L Thompson // Get output vector 6371d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opoutputfields[out], &vec); 6381d102b48SJeremy L Thompson CeedChk(ierr); 6391d102b48SJeremy L Thompson // Check if active output 6401d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 6411d102b48SJeremy L Thompson CeedVectorSetArray(impl->qvecsout[out], CEED_MEM_HOST, 6421d102b48SJeremy L Thompson CEED_USE_POINTER, a); CeedChk(ierr); 6431d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetSize(qfoutputfields[out], &size); 6441d102b48SJeremy L Thompson CeedChk(ierr); 6451d102b48SJeremy L Thompson a += size*Q; // Advance the pointer by the size of the output 6461d102b48SJeremy L Thompson } 6471d102b48SJeremy L Thompson } 6481d102b48SJeremy L Thompson // Apply QFunction 6491d102b48SJeremy L Thompson ierr = CeedQFunctionApply(qf, Q, impl->qvecsin, impl->qvecsout); 6501d102b48SJeremy L Thompson CeedChk(ierr); 6511d102b48SJeremy L Thompson } 6521d102b48SJeremy L Thompson } 6531d102b48SJeremy L Thompson 6541d102b48SJeremy L Thompson // Un-set output Qvecs to prevent accidental overwrite of Assembled 6551d102b48SJeremy L Thompson for (CeedInt out=0; out<numoutputfields; out++) { 6561d102b48SJeremy L Thompson // Get output vector 6571d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opoutputfields[out], &vec); 6581d102b48SJeremy L Thompson CeedChk(ierr); 6591d102b48SJeremy L Thompson // Check if active output 6601d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 6611d102b48SJeremy L Thompson CeedVectorSetArray(impl->qvecsout[out], CEED_MEM_HOST, CEED_COPY_VALUES, 6621d102b48SJeremy L Thompson NULL); CeedChk(ierr); 6631d102b48SJeremy L Thompson } 6641d102b48SJeremy L Thompson } 6651d102b48SJeremy L Thompson 6661d102b48SJeremy L Thompson // Restore input arrays 6671d102b48SJeremy L Thompson ierr = CeedOperatorRestoreInputs_Ref(numinputfields, qfinputfields, 6681d102b48SJeremy L Thompson opinputfields, true, impl); 6691d102b48SJeremy L Thompson CeedChk(ierr); 6701d102b48SJeremy L Thompson 6711d102b48SJeremy L Thompson // Restore output 6721d102b48SJeremy L Thompson ierr = CeedVectorRestoreArray(*assembled, &a); CeedChk(ierr); 6731d102b48SJeremy L Thompson 6741d102b48SJeremy L Thompson // Cleanup 675*42ea3801Sjeremylt for (CeedInt i=0; i<numactivein; i++) { 676*42ea3801Sjeremylt ierr = CeedVectorDestroy(&activein[i]); CeedChk(ierr); 677*42ea3801Sjeremylt } 6781d102b48SJeremy L Thompson ierr = CeedFree(&activein); CeedChk(ierr); 6791d102b48SJeremy L Thompson 6801d102b48SJeremy L Thompson return 0; 6811d102b48SJeremy L Thompson } 6821d102b48SJeremy L Thompson 68321617c04Sjeremylt int CeedOperatorCreate_Ref(CeedOperator op) { 68421617c04Sjeremylt int ierr; 685fe2413ffSjeremylt Ceed ceed; 686fe2413ffSjeremylt ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 6874ce2993fSjeremylt CeedOperator_Ref *impl; 68821617c04Sjeremylt 68921617c04Sjeremylt ierr = CeedCalloc(1, &impl); CeedChk(ierr); 69052d6035fSJeremy L Thompson impl->add = false; 691de686571SJeremy L Thompson ierr = CeedOperatorSetData(op, (void *)&impl); CeedChk(ierr); 692fe2413ffSjeremylt 6931d102b48SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Operator", op, "AssembleLinearQFunction", 6941d102b48SJeremy L Thompson CeedOperatorAssembleLinearQFunction_Ref); 6951d102b48SJeremy L Thompson CeedChk(ierr); 696fe2413ffSjeremylt ierr = CeedSetBackendFunction(ceed, "Operator", op, "Apply", 697fe2413ffSjeremylt CeedOperatorApply_Ref); CeedChk(ierr); 698fe2413ffSjeremylt ierr = CeedSetBackendFunction(ceed, "Operator", op, "Destroy", 699fe2413ffSjeremylt CeedOperatorDestroy_Ref); CeedChk(ierr); 70021617c04Sjeremylt return 0; 70121617c04Sjeremylt } 70252d6035fSJeremy L Thompson 70352d6035fSJeremy L Thompson int CeedCompositeOperatorCreate_Ref(CeedOperator op) { 70452d6035fSJeremy L Thompson int ierr; 70552d6035fSJeremy L Thompson Ceed ceed; 70652d6035fSJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 70752d6035fSJeremy L Thompson 70852d6035fSJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Operator", op, "Apply", 70952d6035fSJeremy L Thompson CeedCompositeOperatorApply_Ref); CeedChk(ierr); 71052d6035fSJeremy L Thompson return 0; 71152d6035fSJeremy L Thompson } 712