14a2e7687Sjeremylt // Copyright (c) 2017-2018, Lawrence Livermore National Security, LLC. 24a2e7687Sjeremylt // Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707. 34a2e7687Sjeremylt // All Rights reserved. See files LICENSE and NOTICE for details. 44a2e7687Sjeremylt // 54a2e7687Sjeremylt // This file is part of CEED, a collection of benchmarks, miniapps, software 64a2e7687Sjeremylt // libraries and APIs for efficient high-order finite element and spectral 74a2e7687Sjeremylt // element discretizations for exascale applications. For more information and 84a2e7687Sjeremylt // source code availability see http://github.com/ceed. 94a2e7687Sjeremylt // 104a2e7687Sjeremylt // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 114a2e7687Sjeremylt // a collaborative effort of two U.S. Department of Energy organizations (Office 124a2e7687Sjeremylt // of Science and the National Nuclear Security Administration) responsible for 134a2e7687Sjeremylt // the planning and preparation of a capable exascale ecosystem, including 144a2e7687Sjeremylt // software, applications, hardware, advanced system engineering and early 154a2e7687Sjeremylt // testbed platforms, in support of the nation's exascale computing imperative. 164a2e7687Sjeremylt 174a2e7687Sjeremylt #include "ceed-blocked.h" 184a2e7687Sjeremylt #include "../ref/ceed-ref.h" 194a2e7687Sjeremylt 20f10650afSjeremylt //------------------------------------------------------------------------------ 21f10650afSjeremylt // Setup Input/Output Fields 22f10650afSjeremylt //------------------------------------------------------------------------------ 2389c6efa4Sjeremylt static int CeedOperatorSetupFields_Blocked(CeedQFunction qf, 2489c6efa4Sjeremylt CeedOperator op, bool inOrOut, 254a2e7687Sjeremylt CeedElemRestriction *blkrestr, 2691703d3fSjeremylt CeedVector *fullevecs, CeedVector *evecs, 27aedaa0e5Sjeremylt CeedVector *qvecs, CeedInt starte, 284a2e7687Sjeremylt CeedInt numfields, CeedInt Q) { 294d537eeaSYohann CeedInt dim, ierr, ncomp, size, P; 30aedaa0e5Sjeremylt Ceed ceed; 31aedaa0e5Sjeremylt ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 32d1bcdac9Sjeremylt CeedBasis basis; 33d1bcdac9Sjeremylt CeedElemRestriction r; 34aedaa0e5Sjeremylt CeedOperatorField *opfields; 35aedaa0e5Sjeremylt CeedQFunctionField *qffields; 36fe2413ffSjeremylt if (inOrOut) { 37aedaa0e5Sjeremylt ierr = CeedOperatorGetFields(op, NULL, &opfields); 38fe2413ffSjeremylt CeedChk(ierr); 39aedaa0e5Sjeremylt ierr = CeedQFunctionGetFields(qf, NULL, &qffields); 40fe2413ffSjeremylt CeedChk(ierr); 41fe2413ffSjeremylt } else { 42aedaa0e5Sjeremylt ierr = CeedOperatorGetFields(op, &opfields, NULL); 43fe2413ffSjeremylt CeedChk(ierr); 44aedaa0e5Sjeremylt ierr = CeedQFunctionGetFields(qf, &qffields, NULL); 45fe2413ffSjeremylt CeedChk(ierr); 46fe2413ffSjeremylt } 474a2e7687Sjeremylt const CeedInt blksize = 8; 484a2e7687Sjeremylt 494a2e7687Sjeremylt // Loop over fields 504a2e7687Sjeremylt for (CeedInt i=0; i<numfields; i++) { 51d1bcdac9Sjeremylt CeedEvalMode emode; 52aedaa0e5Sjeremylt ierr = CeedQFunctionFieldGetEvalMode(qffields[i], &emode); CeedChk(ierr); 534a2e7687Sjeremylt 544a2e7687Sjeremylt if (emode != CEED_EVAL_WEIGHT) { 55aedaa0e5Sjeremylt ierr = CeedOperatorFieldGetElemRestriction(opfields[i], &r); 56d1bcdac9Sjeremylt CeedChk(ierr); 57fe2413ffSjeremylt CeedElemRestriction_Ref *data; 58de686571SJeremy L Thompson ierr = CeedElemRestrictionGetData(r, (void *)&data); CeedChk(ierr); 594ce2993fSjeremylt Ceed ceed; 604ce2993fSjeremylt ierr = CeedElemRestrictionGetCeed(r, &ceed); CeedChk(ierr); 618795c945Sjeremylt CeedInt nelem, elemsize, nnodes; 62*61dbc9d2Sjeremylt CeedInterlaceMode imode; 63*61dbc9d2Sjeremylt ierr = CeedElemRestrictionGetIMode(r, &imode); CeedChk(ierr); 644ce2993fSjeremylt ierr = CeedElemRestrictionGetNumElements(r, &nelem); CeedChk(ierr); 654ce2993fSjeremylt ierr = CeedElemRestrictionGetElementSize(r, &elemsize); CeedChk(ierr); 668795c945Sjeremylt ierr = CeedElemRestrictionGetNumNodes(r, &nnodes); CeedChk(ierr); 674ce2993fSjeremylt ierr = CeedElemRestrictionGetNumComponents(r, &ncomp); CeedChk(ierr); 68*61dbc9d2Sjeremylt ierr = CeedElemRestrictionCreateBlocked(ceed, imode, nelem, elemsize, 698795c945Sjeremylt blksize, nnodes, ncomp, 704a2e7687Sjeremylt CEED_MEM_HOST, CEED_COPY_VALUES, 71aedaa0e5Sjeremylt data->indices, &blkrestr[i+starte]); 724a2e7687Sjeremylt CeedChk(ierr); 73aedaa0e5Sjeremylt ierr = CeedElemRestrictionCreateVector(blkrestr[i+starte], NULL, 7491703d3fSjeremylt &fullevecs[i+starte]); 754a2e7687Sjeremylt CeedChk(ierr); 764a2e7687Sjeremylt } 774a2e7687Sjeremylt 784a2e7687Sjeremylt switch(emode) { 794a2e7687Sjeremylt case CEED_EVAL_NONE: 804d537eeaSYohann ierr = CeedQFunctionFieldGetSize(qffields[i], &size); CeedChk(ierr); 814d537eeaSYohann ierr = CeedVectorCreate(ceed, Q*size*blksize, &qvecs[i]); CeedChk(ierr); 82aedaa0e5Sjeremylt break; 83aedaa0e5Sjeremylt case CEED_EVAL_INTERP: 844d537eeaSYohann ierr = CeedQFunctionFieldGetSize(qffields[i], &size); CeedChk(ierr); 854d1cd9fcSJeremy L Thompson ierr = CeedElemRestrictionGetElementSize(r, &P); 864d1cd9fcSJeremy L Thompson CeedChk(ierr); 874d537eeaSYohann ierr = CeedVectorCreate(ceed, P*size*blksize, &evecs[i]); CeedChk(ierr); 884d537eeaSYohann ierr = CeedVectorCreate(ceed, Q*size*blksize, &qvecs[i]); CeedChk(ierr); 894a2e7687Sjeremylt break; 904a2e7687Sjeremylt case CEED_EVAL_GRAD: 91aedaa0e5Sjeremylt ierr = CeedOperatorFieldGetBasis(opfields[i], &basis); CeedChk(ierr); 924d537eeaSYohann ierr = CeedQFunctionFieldGetSize(qffields[i], &size); CeedChk(ierr); 93d1bcdac9Sjeremylt ierr = CeedBasisGetDimension(basis, &dim); CeedChk(ierr); 944d1cd9fcSJeremy L Thompson ierr = CeedElemRestrictionGetElementSize(r, &P); 954d1cd9fcSJeremy L Thompson CeedChk(ierr); 964d537eeaSYohann ierr = CeedVectorCreate(ceed, P*size/dim*blksize, &evecs[i]); CeedChk(ierr); 974d537eeaSYohann ierr = CeedVectorCreate(ceed, Q*size*blksize, &qvecs[i]); CeedChk(ierr); 984a2e7687Sjeremylt break; 994a2e7687Sjeremylt case CEED_EVAL_WEIGHT: // Only on input fields 100aedaa0e5Sjeremylt ierr = CeedOperatorFieldGetBasis(opfields[i], &basis); CeedChk(ierr); 101aedaa0e5Sjeremylt ierr = CeedVectorCreate(ceed, Q*blksize, &qvecs[i]); CeedChk(ierr); 102d1bcdac9Sjeremylt ierr = CeedBasisApply(basis, blksize, CEED_NOTRANSPOSE, 103a7b7f929Sjeremylt CEED_EVAL_WEIGHT, CEED_VECTOR_NONE, qvecs[i]); 104a7b7f929Sjeremylt CeedChk(ierr); 105aedaa0e5Sjeremylt 1064a2e7687Sjeremylt break; 1074a2e7687Sjeremylt case CEED_EVAL_DIV: 1084d537eeaSYohann break; // Not implemented 1094a2e7687Sjeremylt case CEED_EVAL_CURL: 1104d537eeaSYohann break; // Not implemented 1114a2e7687Sjeremylt } 1124a2e7687Sjeremylt } 1134a2e7687Sjeremylt return 0; 1144a2e7687Sjeremylt } 1154a2e7687Sjeremylt 116f10650afSjeremylt //------------------------------------------------------------------------------ 117f10650afSjeremylt // Setup Operator 118f10650afSjeremylt //------------------------------------------------------------------------------ 1194a2e7687Sjeremylt static int CeedOperatorSetup_Blocked(CeedOperator op) { 1204a2e7687Sjeremylt int ierr; 1214ce2993fSjeremylt bool setupdone; 1224ce2993fSjeremylt ierr = CeedOperatorGetSetupStatus(op, &setupdone); CeedChk(ierr); 1234ce2993fSjeremylt if (setupdone) return 0; 124aedaa0e5Sjeremylt Ceed ceed; 125aedaa0e5Sjeremylt ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 1264ce2993fSjeremylt CeedOperator_Blocked *impl; 1274ce2993fSjeremylt ierr = CeedOperatorGetData(op, (void *)&impl); CeedChk(ierr); 1284ce2993fSjeremylt CeedQFunction qf; 1294ce2993fSjeremylt ierr = CeedOperatorGetQFunction(op, &qf); CeedChk(ierr); 1304ce2993fSjeremylt CeedInt Q, numinputfields, numoutputfields; 1314ce2993fSjeremylt ierr = CeedOperatorGetNumQuadraturePoints(op, &Q); CeedChk(ierr); 13216911fdaSjeremylt ierr = CeedQFunctionGetIdentityStatus(qf, &impl->identityqf); CeedChk(ierr); 1334a2e7687Sjeremylt ierr= CeedQFunctionGetNumArgs(qf, &numinputfields, &numoutputfields); 1344a2e7687Sjeremylt 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); 1414a2e7687Sjeremylt 1424a2e7687Sjeremylt // Allocate 143aedaa0e5Sjeremylt ierr = CeedCalloc(numinputfields + numoutputfields, &impl->blkrestr); 1444a2e7687Sjeremylt CeedChk(ierr); 145aedaa0e5Sjeremylt ierr = CeedCalloc(numinputfields + numoutputfields, &impl->evecs); 1464a2e7687Sjeremylt CeedChk(ierr); 147aedaa0e5Sjeremylt ierr = CeedCalloc(numinputfields + numoutputfields, &impl->edata); 1484a2e7687Sjeremylt CeedChk(ierr); 1494a2e7687Sjeremylt 15016c359e6Sjeremylt ierr = CeedCalloc(16, &impl->inputstate); CeedChk(ierr); 15191703d3fSjeremylt ierr = CeedCalloc(16, &impl->evecsin); CeedChk(ierr); 15291703d3fSjeremylt ierr = CeedCalloc(16, &impl->evecsout); CeedChk(ierr); 153aedaa0e5Sjeremylt ierr = CeedCalloc(16, &impl->qvecsin); CeedChk(ierr); 154aedaa0e5Sjeremylt ierr = CeedCalloc(16, &impl->qvecsout); CeedChk(ierr); 1554a2e7687Sjeremylt 156aedaa0e5Sjeremylt impl->numein = numinputfields; impl->numeout = numoutputfields; 157aedaa0e5Sjeremylt 1584a2e7687Sjeremylt // Set up infield and outfield pointer arrays 1594a2e7687Sjeremylt // Infields 160aedaa0e5Sjeremylt ierr = CeedOperatorSetupFields_Blocked(qf, op, 0, impl->blkrestr, 16191703d3fSjeremylt impl->evecs, impl->evecsin, 16291703d3fSjeremylt impl->qvecsin, 0, 163aedaa0e5Sjeremylt numinputfields, Q); 1644a2e7687Sjeremylt CeedChk(ierr); 1654a2e7687Sjeremylt // Outfields 166aedaa0e5Sjeremylt ierr = CeedOperatorSetupFields_Blocked(qf, op, 1, impl->blkrestr, 16791703d3fSjeremylt impl->evecs, impl->evecsout, 16891703d3fSjeremylt impl->qvecsout, numinputfields, 16991703d3fSjeremylt numoutputfields, Q); 1704a2e7687Sjeremylt CeedChk(ierr); 171aedaa0e5Sjeremylt 17216911fdaSjeremylt // Identity QFunctions 17316911fdaSjeremylt if (impl->identityqf) { 17416911fdaSjeremylt CeedEvalMode inmode, outmode; 17516911fdaSjeremylt CeedQFunctionField *infields, *outfields; 17616911fdaSjeremylt ierr = CeedQFunctionGetFields(qf, &infields, &outfields); CeedChk(ierr); 17716911fdaSjeremylt 17816911fdaSjeremylt for (CeedInt i=0; i<numinputfields; i++) { 17916911fdaSjeremylt ierr = CeedQFunctionFieldGetEvalMode(infields[i], &inmode); 18016911fdaSjeremylt CeedChk(ierr); 18116911fdaSjeremylt ierr = CeedQFunctionFieldGetEvalMode(outfields[i], &outmode); 18216911fdaSjeremylt CeedChk(ierr); 18316911fdaSjeremylt 18416911fdaSjeremylt ierr = CeedVectorDestroy(&impl->qvecsout[i]); CeedChk(ierr); 18516911fdaSjeremylt impl->qvecsout[i] = impl->qvecsin[i]; 18655e4cc5bSjeremylt ierr = CeedVectorAddReference(impl->qvecsin[i]); CeedChk(ierr); 18716911fdaSjeremylt } 18816911fdaSjeremylt } 18916911fdaSjeremylt 1904ce2993fSjeremylt ierr = CeedOperatorSetSetupDone(op); CeedChk(ierr); 1914a2e7687Sjeremylt 1924a2e7687Sjeremylt return 0; 1934a2e7687Sjeremylt } 1944a2e7687Sjeremylt 195f10650afSjeremylt //------------------------------------------------------------------------------ 196f10650afSjeremylt // Setup Operator Inputs 197f10650afSjeremylt //------------------------------------------------------------------------------ 1981d102b48SJeremy L Thompson static inline int CeedOperatorSetupInputs_Blocked(CeedInt numinputfields, 1991d102b48SJeremy L Thompson CeedQFunctionField *qfinputfields, CeedOperatorField *opinputfields, 2001d102b48SJeremy L Thompson CeedVector invec, bool skipactive, CeedOperator_Blocked *impl, 20189c6efa4Sjeremylt CeedRequest *request) { 2021d102b48SJeremy L Thompson CeedInt ierr; 203d1bcdac9Sjeremylt CeedEvalMode emode; 204d1bcdac9Sjeremylt CeedVector vec; 20516c359e6Sjeremylt uint64_t state; 2064a2e7687Sjeremylt 2074a2e7687Sjeremylt for (CeedInt i=0; i<numinputfields; i++) { 2081d102b48SJeremy L Thompson // Get input vector 2091d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opinputfields[i], &vec); CeedChk(ierr); 2101d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 2111d102b48SJeremy L Thompson if (skipactive) 2121d102b48SJeremy L Thompson continue; 2131d102b48SJeremy L Thompson else 2141d102b48SJeremy L Thompson vec = invec; 2151d102b48SJeremy L Thompson } 2161d102b48SJeremy L Thompson 217d1bcdac9Sjeremylt ierr = CeedQFunctionFieldGetEvalMode(qfinputfields[i], &emode); 218d1bcdac9Sjeremylt CeedChk(ierr); 2194a2e7687Sjeremylt if (emode == CEED_EVAL_WEIGHT) { // Skip 2204a2e7687Sjeremylt } else { 2214a2e7687Sjeremylt // Restrict 22216c359e6Sjeremylt ierr = CeedVectorGetState(vec, &state); CeedChk(ierr); 22389c6efa4Sjeremylt if (state != impl->inputstate[i] || vec == invec) { 2244a2e7687Sjeremylt ierr = CeedElemRestrictionApply(impl->blkrestr[i], CEED_NOTRANSPOSE, 225a8d32208Sjeremylt vec, impl->evecs[i], request); 226a8d32208Sjeremylt CeedChk(ierr); 22716c359e6Sjeremylt impl->inputstate[i] = state; 22816c359e6Sjeremylt } 2294a2e7687Sjeremylt // Get evec 2304a2e7687Sjeremylt ierr = CeedVectorGetArrayRead(impl->evecs[i], CEED_MEM_HOST, 2314a2e7687Sjeremylt (const CeedScalar **) &impl->edata[i]); 2324a2e7687Sjeremylt CeedChk(ierr); 2334a2e7687Sjeremylt } 2344a2e7687Sjeremylt } 2351d102b48SJeremy L Thompson return 0; 2364a2e7687Sjeremylt } 2374a2e7687Sjeremylt 238f10650afSjeremylt //------------------------------------------------------------------------------ 239f10650afSjeremylt // Input Basis Action 240f10650afSjeremylt //------------------------------------------------------------------------------ 2411d102b48SJeremy L Thompson static inline int CeedOperatorInputBasis_Blocked(CeedInt e, CeedInt Q, 2421d102b48SJeremy L Thompson CeedQFunctionField *qfinputfields, CeedOperatorField *opinputfields, 2431d102b48SJeremy L Thompson CeedInt numinputfields, CeedInt blksize, bool skipactive, 2441d102b48SJeremy L Thompson CeedOperator_Blocked *impl) { 2451d102b48SJeremy L Thompson CeedInt ierr; 2461d102b48SJeremy L Thompson CeedInt dim, elemsize, size; 2471d102b48SJeremy L Thompson CeedElemRestriction Erestrict; 2481d102b48SJeremy L Thompson CeedEvalMode emode; 2491d102b48SJeremy L Thompson CeedBasis basis; 2501d102b48SJeremy L Thompson 2514a2e7687Sjeremylt for (CeedInt i=0; i<numinputfields; i++) { 2521d102b48SJeremy L Thompson // Skip active input 2531d102b48SJeremy L Thompson if (skipactive) { 2541d102b48SJeremy L Thompson CeedVector vec; 2551d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opinputfields[i], &vec); CeedChk(ierr); 2561d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) 2571d102b48SJeremy L Thompson continue; 2581d102b48SJeremy L Thompson } 2591d102b48SJeremy L Thompson 2604d537eeaSYohann // Get elemsize, emode, size 261d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetElemRestriction(opinputfields[i], &Erestrict); 262d1bcdac9Sjeremylt CeedChk(ierr); 263d1bcdac9Sjeremylt ierr = CeedElemRestrictionGetElementSize(Erestrict, &elemsize); 264d1bcdac9Sjeremylt CeedChk(ierr); 265d1bcdac9Sjeremylt ierr = CeedQFunctionFieldGetEvalMode(qfinputfields[i], &emode); 266d1bcdac9Sjeremylt CeedChk(ierr); 2674d537eeaSYohann ierr = CeedQFunctionFieldGetSize(qfinputfields[i], &size); CeedChk(ierr); 2684a2e7687Sjeremylt // Basis action 2694a2e7687Sjeremylt switch(emode) { 2704a2e7687Sjeremylt case CEED_EVAL_NONE: 271aedaa0e5Sjeremylt ierr = CeedVectorSetArray(impl->qvecsin[i], CEED_MEM_HOST, 272aedaa0e5Sjeremylt CEED_USE_POINTER, 2734d537eeaSYohann &impl->edata[i][e*Q*size]); CeedChk(ierr); 2744a2e7687Sjeremylt break; 2754a2e7687Sjeremylt case CEED_EVAL_INTERP: 27689c6efa4Sjeremylt ierr = CeedOperatorFieldGetBasis(opinputfields[i], &basis); CeedChk(ierr); 27791703d3fSjeremylt ierr = CeedVectorSetArray(impl->evecsin[i], CEED_MEM_HOST, 278aedaa0e5Sjeremylt CEED_USE_POINTER, 2794d537eeaSYohann &impl->edata[i][e*elemsize*size]); 2804a2e7687Sjeremylt CeedChk(ierr); 281d1bcdac9Sjeremylt ierr = CeedBasisApply(basis, blksize, CEED_NOTRANSPOSE, 28291703d3fSjeremylt CEED_EVAL_INTERP, impl->evecsin[i], 283aedaa0e5Sjeremylt impl->qvecsin[i]); CeedChk(ierr); 2844a2e7687Sjeremylt break; 2854a2e7687Sjeremylt case CEED_EVAL_GRAD: 28689c6efa4Sjeremylt ierr = CeedOperatorFieldGetBasis(opinputfields[i], &basis); CeedChk(ierr); 2874d537eeaSYohann ierr = CeedBasisGetDimension(basis, &dim); CeedChk(ierr); 28891703d3fSjeremylt ierr = CeedVectorSetArray(impl->evecsin[i], CEED_MEM_HOST, 289aedaa0e5Sjeremylt CEED_USE_POINTER, 2904d537eeaSYohann &impl->edata[i][e*elemsize*size/dim]); 2914a2e7687Sjeremylt CeedChk(ierr); 292d1bcdac9Sjeremylt ierr = CeedBasisApply(basis, blksize, CEED_NOTRANSPOSE, 29391703d3fSjeremylt CEED_EVAL_GRAD, impl->evecsin[i], 294aedaa0e5Sjeremylt impl->qvecsin[i]); CeedChk(ierr); 2954a2e7687Sjeremylt break; 2964a2e7687Sjeremylt case CEED_EVAL_WEIGHT: 2974a2e7687Sjeremylt break; // No action 2984a2e7687Sjeremylt case CEED_EVAL_DIV: 2991d102b48SJeremy L Thompson case CEED_EVAL_CURL: { 3001d102b48SJeremy L Thompson // LCOV_EXCL_START 3011d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetBasis(opinputfields[i], &basis); 3021d102b48SJeremy L Thompson CeedChk(ierr); 3031d102b48SJeremy L Thompson Ceed ceed; 3041d102b48SJeremy L Thompson ierr = CeedBasisGetCeed(basis, &ceed); CeedChk(ierr); 3051d102b48SJeremy L Thompson return CeedError(ceed, 1, "Ceed evaluation mode not implemented"); 3061d102b48SJeremy L Thompson // LCOV_EXCL_STOP 3078c91a0c9SJeremy L Thompson break; // Not implemented 3084a2e7687Sjeremylt } 3094a2e7687Sjeremylt } 31089c6efa4Sjeremylt } 3111d102b48SJeremy L Thompson return 0; 31289c6efa4Sjeremylt } 3134a2e7687Sjeremylt 314f10650afSjeremylt //------------------------------------------------------------------------------ 315f10650afSjeremylt // Output Basis Action 316f10650afSjeremylt //------------------------------------------------------------------------------ 3171d102b48SJeremy L Thompson static inline int CeedOperatorOutputBasis_Blocked(CeedInt e, CeedInt Q, 3181d102b48SJeremy L Thompson CeedQFunctionField *qfoutputfields, CeedOperatorField *opoutputfields, 3191d102b48SJeremy L Thompson CeedInt blksize, CeedInt numinputfields, CeedInt numoutputfields, 3201d102b48SJeremy L Thompson CeedOperator op, CeedOperator_Blocked *impl) { 3211d102b48SJeremy L Thompson CeedInt ierr; 3221d102b48SJeremy L Thompson CeedInt dim, elemsize, size; 3231d102b48SJeremy L Thompson CeedElemRestriction Erestrict; 3241d102b48SJeremy L Thompson CeedEvalMode emode; 3251d102b48SJeremy L Thompson CeedBasis basis; 3261d102b48SJeremy L Thompson 3274a2e7687Sjeremylt for (CeedInt i=0; i<numoutputfields; i++) { 3284d537eeaSYohann // Get elemsize, emode, size 329d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetElemRestriction(opoutputfields[i], &Erestrict); 330d1bcdac9Sjeremylt CeedChk(ierr); 33189c6efa4Sjeremylt ierr = CeedElemRestrictionGetElementSize(Erestrict, &elemsize); 33289c6efa4Sjeremylt CeedChk(ierr); 333d1bcdac9Sjeremylt ierr = CeedQFunctionFieldGetEvalMode(qfoutputfields[i], &emode); 334d1bcdac9Sjeremylt CeedChk(ierr); 3354d537eeaSYohann ierr = CeedQFunctionFieldGetSize(qfoutputfields[i], &size); CeedChk(ierr); 3364a2e7687Sjeremylt // Basis action 3374a2e7687Sjeremylt switch(emode) { 3384a2e7687Sjeremylt case CEED_EVAL_NONE: 3394a2e7687Sjeremylt break; // No action 3404a2e7687Sjeremylt case CEED_EVAL_INTERP: 341d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetBasis(opoutputfields[i], &basis); 342d1bcdac9Sjeremylt CeedChk(ierr); 34389c6efa4Sjeremylt ierr = CeedVectorSetArray(impl->evecsout[i], CEED_MEM_HOST, 34489c6efa4Sjeremylt CEED_USE_POINTER, 3454d537eeaSYohann &impl->edata[i + numinputfields][e*elemsize*size]); 34689c6efa4Sjeremylt CeedChk(ierr); 347aedaa0e5Sjeremylt ierr = CeedBasisApply(basis, blksize, CEED_TRANSPOSE, 348aedaa0e5Sjeremylt CEED_EVAL_INTERP, impl->qvecsout[i], 34991703d3fSjeremylt impl->evecsout[i]); CeedChk(ierr); 3504a2e7687Sjeremylt break; 3514a2e7687Sjeremylt case CEED_EVAL_GRAD: 352d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetBasis(opoutputfields[i], &basis); 353d1bcdac9Sjeremylt CeedChk(ierr); 3544d537eeaSYohann ierr = CeedBasisGetDimension(basis, &dim); CeedChk(ierr); 35589c6efa4Sjeremylt ierr = CeedVectorSetArray(impl->evecsout[i], CEED_MEM_HOST, 35689c6efa4Sjeremylt CEED_USE_POINTER, 3574d537eeaSYohann &impl->edata[i + numinputfields][e*elemsize*size/dim]); 35889c6efa4Sjeremylt CeedChk(ierr); 359d1bcdac9Sjeremylt ierr = CeedBasisApply(basis, blksize, CEED_TRANSPOSE, 360aedaa0e5Sjeremylt CEED_EVAL_GRAD, impl->qvecsout[i], 36191703d3fSjeremylt impl->evecsout[i]); CeedChk(ierr); 3624a2e7687Sjeremylt break; 3634ce2993fSjeremylt case CEED_EVAL_WEIGHT: { 364c042f62fSJeremy L Thompson // LCOV_EXCL_START 3654ce2993fSjeremylt Ceed ceed; 3664ce2993fSjeremylt ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 3671d102b48SJeremy L Thompson return CeedError(ceed, 1, "CEED_EVAL_WEIGHT cannot be an output " 3681d102b48SJeremy L Thompson "evaluation mode"); 369c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 3704a2e7687Sjeremylt break; // Should not occur 3714ce2993fSjeremylt } 3724a2e7687Sjeremylt case CEED_EVAL_DIV: 3731d102b48SJeremy L Thompson case CEED_EVAL_CURL: { 3741d102b48SJeremy L Thompson // LCOV_EXCL_START 3751d102b48SJeremy L Thompson Ceed ceed; 3761d102b48SJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 3771d102b48SJeremy L Thompson return CeedError(ceed, 1, "Ceed evaluation mode not implemented"); 3781d102b48SJeremy L Thompson // LCOV_EXCL_STOP 3798c91a0c9SJeremy L Thompson break; // Not implemented 3804a2e7687Sjeremylt } 38189c6efa4Sjeremylt } 38289c6efa4Sjeremylt } 3831d102b48SJeremy L Thompson return 0; 3841d102b48SJeremy L Thompson } 3851d102b48SJeremy L Thompson 386f10650afSjeremylt //------------------------------------------------------------------------------ 387f10650afSjeremylt // Restore Input Vectors 388f10650afSjeremylt //------------------------------------------------------------------------------ 3891d102b48SJeremy L Thompson static inline int CeedOperatorRestoreInputs_Blocked(CeedInt numinputfields, 3901d102b48SJeremy L Thompson CeedQFunctionField *qfinputfields, CeedOperatorField *opinputfields, 3911d102b48SJeremy L Thompson bool skipactive, CeedOperator_Blocked *impl) { 3921d102b48SJeremy L Thompson CeedInt ierr; 3931d102b48SJeremy L Thompson CeedEvalMode emode; 3941d102b48SJeremy L Thompson 3951d102b48SJeremy L Thompson for (CeedInt i=0; i<numinputfields; i++) { 3961d102b48SJeremy L Thompson // Skip active inputs 3971d102b48SJeremy L Thompson if (skipactive) { 3981d102b48SJeremy L Thompson CeedVector vec; 3991d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opinputfields[i], &vec); CeedChk(ierr); 4001d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) 4011d102b48SJeremy L Thompson continue; 4021d102b48SJeremy L Thompson } 4031d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetEvalMode(qfinputfields[i], &emode); 4041d102b48SJeremy L Thompson CeedChk(ierr); 4051d102b48SJeremy L Thompson if (emode == CEED_EVAL_WEIGHT) { // Skip 4061d102b48SJeremy L Thompson } else { 4071d102b48SJeremy L Thompson ierr = CeedVectorRestoreArrayRead(impl->evecs[i], 4081d102b48SJeremy L Thompson (const CeedScalar **) &impl->edata[i]); 4091d102b48SJeremy L Thompson CeedChk(ierr); 4101d102b48SJeremy L Thompson } 4111d102b48SJeremy L Thompson } 4121d102b48SJeremy L Thompson return 0; 4131d102b48SJeremy L Thompson } 4141d102b48SJeremy L Thompson 415f10650afSjeremylt //------------------------------------------------------------------------------ 416f10650afSjeremylt // Operator Apply 417f10650afSjeremylt //------------------------------------------------------------------------------ 4181d102b48SJeremy L Thompson static int CeedOperatorApply_Blocked(CeedOperator op, CeedVector invec, 4191d102b48SJeremy L Thompson CeedVector outvec, 4201d102b48SJeremy L Thompson CeedRequest *request) { 4211d102b48SJeremy L Thompson int ierr; 4221d102b48SJeremy L Thompson CeedOperator_Blocked *impl; 4231d102b48SJeremy L Thompson ierr = CeedOperatorGetData(op, (void *)&impl); CeedChk(ierr); 4241d102b48SJeremy L Thompson const CeedInt blksize = 8; 4251d102b48SJeremy L Thompson CeedInt Q, numinputfields, numoutputfields, numelements, size; 4261d102b48SJeremy L Thompson ierr = CeedOperatorGetNumElements(op, &numelements); CeedChk(ierr); 4271d102b48SJeremy L Thompson ierr = CeedOperatorGetNumQuadraturePoints(op, &Q); CeedChk(ierr); 4281d102b48SJeremy L Thompson CeedInt nblks = (numelements/blksize) + !!(numelements%blksize); 4291d102b48SJeremy L Thompson CeedQFunction qf; 4301d102b48SJeremy L Thompson ierr = CeedOperatorGetQFunction(op, &qf); CeedChk(ierr); 4311d102b48SJeremy L Thompson ierr= CeedQFunctionGetNumArgs(qf, &numinputfields, &numoutputfields); 4321d102b48SJeremy L Thompson CeedChk(ierr); 4331d102b48SJeremy L Thompson CeedOperatorField *opinputfields, *opoutputfields; 4341d102b48SJeremy L Thompson ierr = CeedOperatorGetFields(op, &opinputfields, &opoutputfields); 4351d102b48SJeremy L Thompson CeedChk(ierr); 4361d102b48SJeremy L Thompson CeedQFunctionField *qfinputfields, *qfoutputfields; 4371d102b48SJeremy L Thompson ierr = CeedQFunctionGetFields(qf, &qfinputfields, &qfoutputfields); 4381d102b48SJeremy L Thompson CeedChk(ierr); 4391d102b48SJeremy L Thompson CeedEvalMode emode; 4401d102b48SJeremy L Thompson CeedVector vec; 4411d102b48SJeremy L Thompson 4421d102b48SJeremy L Thompson // Setup 4431d102b48SJeremy L Thompson ierr = CeedOperatorSetup_Blocked(op); CeedChk(ierr); 4441d102b48SJeremy L Thompson 4451d102b48SJeremy L Thompson // Input Evecs and Restriction 4461d102b48SJeremy L Thompson ierr = CeedOperatorSetupInputs_Blocked(numinputfields, qfinputfields, 4477f823360Sjeremylt opinputfields, invec, false, impl, 4487f823360Sjeremylt request); CeedChk(ierr); 4491d102b48SJeremy L Thompson 4501d102b48SJeremy L Thompson // Output Evecs 4511d102b48SJeremy L Thompson for (CeedInt i=0; i<numoutputfields; i++) { 4521d102b48SJeremy L Thompson ierr = CeedVectorGetArray(impl->evecs[i+impl->numein], CEED_MEM_HOST, 4531d102b48SJeremy L Thompson &impl->edata[i + numinputfields]); CeedChk(ierr); 4541d102b48SJeremy L Thompson } 4551d102b48SJeremy L Thompson 4561d102b48SJeremy L Thompson // Loop through elements 4571d102b48SJeremy L Thompson for (CeedInt e=0; e<nblks*blksize; e+=blksize) { 4581d102b48SJeremy L Thompson // Output pointers 4591d102b48SJeremy L Thompson for (CeedInt i=0; i<numoutputfields; i++) { 4601d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetEvalMode(qfoutputfields[i], &emode); 4611d102b48SJeremy L Thompson CeedChk(ierr); 4621d102b48SJeremy L Thompson if (emode == CEED_EVAL_NONE) { 4631d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetSize(qfoutputfields[i], &size); 4641d102b48SJeremy L Thompson CeedChk(ierr); 4651d102b48SJeremy L Thompson ierr = CeedVectorSetArray(impl->qvecsout[i], CEED_MEM_HOST, 4661d102b48SJeremy L Thompson CEED_USE_POINTER, 4671d102b48SJeremy L Thompson &impl->edata[i + numinputfields][e*Q*size]); 4681d102b48SJeremy L Thompson CeedChk(ierr); 4691d102b48SJeremy L Thompson } 4701d102b48SJeremy L Thompson } 4711d102b48SJeremy L Thompson 47216911fdaSjeremylt // Input basis apply 47316911fdaSjeremylt ierr = CeedOperatorInputBasis_Blocked(e, Q, qfinputfields, opinputfields, 47416911fdaSjeremylt numinputfields, blksize, false, impl); 47516911fdaSjeremylt CeedChk(ierr); 47616911fdaSjeremylt 4771d102b48SJeremy L Thompson // Q function 47816911fdaSjeremylt if (!impl->identityqf) { 4791d102b48SJeremy L Thompson ierr = CeedQFunctionApply(qf, Q*blksize, impl->qvecsin, impl->qvecsout); 4801d102b48SJeremy L Thompson CeedChk(ierr); 48116911fdaSjeremylt } 4821d102b48SJeremy L Thompson 4831d102b48SJeremy L Thompson // Output basis apply 4841d102b48SJeremy L Thompson ierr = CeedOperatorOutputBasis_Blocked(e, Q, qfoutputfields, opoutputfields, 4857f823360Sjeremylt blksize, numinputfields, 4867f823360Sjeremylt numoutputfields, op, impl); 4871d102b48SJeremy L Thompson CeedChk(ierr); 4881d102b48SJeremy L Thompson } 48989c6efa4Sjeremylt 49089c6efa4Sjeremylt // Output restriction 49189c6efa4Sjeremylt for (CeedInt i=0; i<numoutputfields; i++) { 49289c6efa4Sjeremylt // Restore evec 49389c6efa4Sjeremylt ierr = CeedVectorRestoreArray(impl->evecs[i+impl->numein], 49489c6efa4Sjeremylt &impl->edata[i + numinputfields]); CeedChk(ierr); 495d1bcdac9Sjeremylt // Get output vector 496d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetVector(opoutputfields[i], &vec); CeedChk(ierr); 49789c6efa4Sjeremylt // Active 498d1bcdac9Sjeremylt if (vec == CEED_VECTOR_ACTIVE) 499d1bcdac9Sjeremylt vec = outvec; 5004a2e7687Sjeremylt // Restrict 501a8d32208Sjeremylt ierr = CeedElemRestrictionApply(impl->blkrestr[i+impl->numein], 502a8d32208Sjeremylt CEED_TRANSPOSE, impl->evecs[i+impl->numein], 503a8d32208Sjeremylt vec, request); CeedChk(ierr); 50489c6efa4Sjeremylt 5054a2e7687Sjeremylt } 5064a2e7687Sjeremylt 5074a2e7687Sjeremylt // Restore input arrays 5081d102b48SJeremy L Thompson ierr = CeedOperatorRestoreInputs_Blocked(numinputfields, qfinputfields, 5097f823360Sjeremylt opinputfields, false, impl); CeedChk(ierr); 5101d102b48SJeremy L Thompson 5111d102b48SJeremy L Thompson return 0; 5121d102b48SJeremy L Thompson } 5131d102b48SJeremy L Thompson 514f10650afSjeremylt //------------------------------------------------------------------------------ 5151d102b48SJeremy L Thompson // Assemble Linear QFunction 516f10650afSjeremylt //------------------------------------------------------------------------------ 5171d102b48SJeremy L Thompson static int CeedOperatorAssembleLinearQFunction_Blocked(CeedOperator op, 5181d102b48SJeremy L Thompson CeedVector *assembled, CeedElemRestriction *rstr, CeedRequest *request) { 5191d102b48SJeremy L Thompson int ierr; 5201d102b48SJeremy L Thompson CeedOperator_Blocked *impl; 5211d102b48SJeremy L Thompson ierr = CeedOperatorGetData(op, (void *)&impl); CeedChk(ierr); 5221d102b48SJeremy L Thompson const CeedInt blksize = 8; 5231d102b48SJeremy L Thompson CeedInt Q, numinputfields, numoutputfields, numelements, size; 5241d102b48SJeremy L Thompson ierr = CeedOperatorGetNumElements(op, &numelements); CeedChk(ierr); 5251d102b48SJeremy L Thompson ierr = CeedOperatorGetNumQuadraturePoints(op, &Q); CeedChk(ierr); 5261d102b48SJeremy L Thompson CeedInt nblks = (numelements/blksize) + !!(numelements%blksize); 5271d102b48SJeremy L Thompson CeedQFunction qf; 5281d102b48SJeremy L Thompson ierr = CeedOperatorGetQFunction(op, &qf); CeedChk(ierr); 5291d102b48SJeremy L Thompson ierr= CeedQFunctionGetNumArgs(qf, &numinputfields, &numoutputfields); 5301d102b48SJeremy L Thompson CeedChk(ierr); 5311d102b48SJeremy L Thompson CeedOperatorField *opinputfields, *opoutputfields; 5321d102b48SJeremy L Thompson ierr = CeedOperatorGetFields(op, &opinputfields, &opoutputfields); 5331d102b48SJeremy L Thompson CeedChk(ierr); 5341d102b48SJeremy L Thompson CeedQFunctionField *qfinputfields, *qfoutputfields; 5351d102b48SJeremy L Thompson ierr = CeedQFunctionGetFields(qf, &qfinputfields, &qfoutputfields); 5361d102b48SJeremy L Thompson CeedChk(ierr); 5371d102b48SJeremy L Thompson CeedVector vec, lvec; 5381d102b48SJeremy L Thompson CeedInt numactivein = 0, numactiveout = 0; 53942ea3801Sjeremylt CeedVector *activein = NULL; 5401d102b48SJeremy L Thompson CeedScalar *a, *tmp; 5411d102b48SJeremy L Thompson Ceed ceed; 5421d102b48SJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 5431d102b48SJeremy L Thompson 5441d102b48SJeremy L Thompson // Setup 5451d102b48SJeremy L Thompson ierr = CeedOperatorSetup_Blocked(op); CeedChk(ierr); 5461d102b48SJeremy L Thompson 54716911fdaSjeremylt // Check for identity 54816911fdaSjeremylt if (impl->identityqf) 54916911fdaSjeremylt // LCOV_EXCL_START 55067db23e4Sjeremylt return CeedError(ceed, 1, "Assembling identity qfunctions not supported"); 55116911fdaSjeremylt // LCOV_EXCL_STOP 55216911fdaSjeremylt 5531d102b48SJeremy L Thompson // Input Evecs and Restriction 5541d102b48SJeremy L Thompson ierr = CeedOperatorSetupInputs_Blocked(numinputfields, qfinputfields, 5551d102b48SJeremy L Thompson opinputfields, NULL, true, impl, 5561d102b48SJeremy L Thompson request); CeedChk(ierr); 5571d102b48SJeremy L Thompson 5581d102b48SJeremy L Thompson // Count number of active input fields 5594a2e7687Sjeremylt for (CeedInt i=0; i<numinputfields; i++) { 5601d102b48SJeremy L Thompson // Get input vector 5611d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opinputfields[i], &vec); CeedChk(ierr); 5621d102b48SJeremy L Thompson // Check if active input 5631d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 5641d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetSize(qfinputfields[i], &size); CeedChk(ierr); 5651d102b48SJeremy L Thompson ierr = CeedVectorSetValue(impl->qvecsin[i], 0.0); CeedChk(ierr); 5661d102b48SJeremy L Thompson ierr = CeedVectorGetArray(impl->qvecsin[i], CEED_MEM_HOST, &tmp); 567d1bcdac9Sjeremylt CeedChk(ierr); 5681d102b48SJeremy L Thompson ierr = CeedRealloc(numactivein + size, &activein); CeedChk(ierr); 5691d102b48SJeremy L Thompson for (CeedInt field=0; field<size; field++) { 57042ea3801Sjeremylt ierr = CeedVectorCreate(ceed, Q*blksize, &activein[numactivein+field]); 57142ea3801Sjeremylt CeedChk(ierr); 57242ea3801Sjeremylt ierr = CeedVectorSetArray(activein[numactivein+field], CEED_MEM_HOST, 57342ea3801Sjeremylt CEED_USE_POINTER, &tmp[field*Q*blksize]); 574112e3f70Sjeremylt CeedChk(ierr); 5751d102b48SJeremy L Thompson } 5761d102b48SJeremy L Thompson numactivein += size; 5771d102b48SJeremy L Thompson ierr = CeedVectorRestoreArray(impl->qvecsin[i], &tmp); CeedChk(ierr); 5781d102b48SJeremy L Thompson } 5791d102b48SJeremy L Thompson } 5801d102b48SJeremy L Thompson 5811d102b48SJeremy L Thompson // Count number of active output fields 5821d102b48SJeremy L Thompson for (CeedInt i=0; i<numoutputfields; i++) { 5831d102b48SJeremy L Thompson // Get output vector 5841d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opoutputfields[i], &vec); CeedChk(ierr); 5851d102b48SJeremy L Thompson // Check if active output 5861d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 5871d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetSize(qfoutputfields[i], &size); CeedChk(ierr); 5881d102b48SJeremy L Thompson numactiveout += size; 5891d102b48SJeremy L Thompson } 5901d102b48SJeremy L Thompson } 5911d102b48SJeremy L Thompson 5921d102b48SJeremy L Thompson // Check sizes 5931d102b48SJeremy L Thompson if (!numactivein || !numactiveout) 5941d102b48SJeremy L Thompson // LCOV_EXCL_START 5951d102b48SJeremy L Thompson return CeedError(ceed, 1, "Cannot assemble QFunction without active inputs " 5961d102b48SJeremy L Thompson "and outputs"); 5971d102b48SJeremy L Thompson // LCOV_EXCL_STOP 5981d102b48SJeremy L Thompson 5991d102b48SJeremy L Thompson // Setup lvec 6001d102b48SJeremy L Thompson ierr = CeedVectorCreate(ceed, nblks*blksize*Q*numactivein*numactiveout, 6011d102b48SJeremy L Thompson &lvec); CeedChk(ierr); 6021d102b48SJeremy L Thompson ierr = CeedVectorGetArray(lvec, CEED_MEM_HOST, &a); CeedChk(ierr); 6031d102b48SJeremy L Thompson 6041d102b48SJeremy L Thompson // Create output restriction 605*61dbc9d2Sjeremylt CeedInterlaceMode imode = CEED_NONINTERLACED; 606*61dbc9d2Sjeremylt ierr = CeedElemRestrictionCreateIdentity(ceed, imode, numelements, Q, 6077f823360Sjeremylt numelements*Q, numactivein*numactiveout, rstr); CeedChk(ierr); 6081d102b48SJeremy L Thompson // Create assembled vector 6091d102b48SJeremy L Thompson ierr = CeedVectorCreate(ceed, numelements*Q*numactivein*numactiveout, 6101d102b48SJeremy L Thompson assembled); CeedChk(ierr); 6111d102b48SJeremy L Thompson 6121d102b48SJeremy L Thompson // Loop through elements 6131d102b48SJeremy L Thompson for (CeedInt e=0; e<nblks*blksize; e+=blksize) { 6141d102b48SJeremy L Thompson // Input basis apply 6151d102b48SJeremy L Thompson ierr = CeedOperatorInputBasis_Blocked(e, Q, qfinputfields, opinputfields, 6161d102b48SJeremy L Thompson numinputfields, blksize, true, impl); 6171d102b48SJeremy L Thompson CeedChk(ierr); 6181d102b48SJeremy L Thompson 6191d102b48SJeremy L Thompson // Assemble QFunction 6201d102b48SJeremy L Thompson for (CeedInt in=0; in<numactivein; in++) { 6211d102b48SJeremy L Thompson // Set Inputs 62242ea3801Sjeremylt ierr = CeedVectorSetValue(activein[in], 1.0); CeedChk(ierr); 62342ea3801Sjeremylt if (numactivein > 1) { 62442ea3801Sjeremylt ierr = CeedVectorSetValue(activein[(in+numactivein-1)%numactivein], 62542ea3801Sjeremylt 0.0); CeedChk(ierr); 62642ea3801Sjeremylt } 6271d102b48SJeremy L Thompson // Set Outputs 6281d102b48SJeremy L Thompson for (CeedInt out=0; out<numoutputfields; out++) { 6291d102b48SJeremy L Thompson // Get output vector 6301d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opoutputfields[out], &vec); 6311d102b48SJeremy L Thompson CeedChk(ierr); 6321d102b48SJeremy L Thompson // Check if active output 6331d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 6341d102b48SJeremy L Thompson CeedVectorSetArray(impl->qvecsout[out], CEED_MEM_HOST, 6351d102b48SJeremy L Thompson CEED_USE_POINTER, a); CeedChk(ierr); 6361d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetSize(qfoutputfields[out], &size); 6371d102b48SJeremy L Thompson CeedChk(ierr); 6381d102b48SJeremy L Thompson a += size*Q*blksize; // Advance the pointer by the size of the output 6391d102b48SJeremy L Thompson } 6401d102b48SJeremy L Thompson } 6411d102b48SJeremy L Thompson // Apply QFunction 6421d102b48SJeremy L Thompson ierr = CeedQFunctionApply(qf, Q*blksize, impl->qvecsin, impl->qvecsout); 643d1bcdac9Sjeremylt CeedChk(ierr); 6444a2e7687Sjeremylt } 6454a2e7687Sjeremylt } 6464a2e7687Sjeremylt 6471d102b48SJeremy L Thompson // Un-set output Qvecs to prevent accidental overwrite of Assembled 6481d102b48SJeremy L Thompson for (CeedInt out=0; out<numoutputfields; out++) { 6491d102b48SJeremy L Thompson // Get output vector 6501d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opoutputfields[out], &vec); 6511d102b48SJeremy L Thompson CeedChk(ierr); 6521d102b48SJeremy L Thompson // Check if active output 6531d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 6541d102b48SJeremy L Thompson CeedVectorSetArray(impl->qvecsout[out], CEED_MEM_HOST, CEED_COPY_VALUES, 6551d102b48SJeremy L Thompson NULL); CeedChk(ierr); 6561d102b48SJeremy L Thompson } 6571d102b48SJeremy L Thompson } 6581d102b48SJeremy L Thompson 6591d102b48SJeremy L Thompson // Restore input arrays 6601d102b48SJeremy L Thompson ierr = CeedOperatorRestoreInputs_Blocked(numinputfields, qfinputfields, 6617f823360Sjeremylt opinputfields, true, impl); CeedChk(ierr); 6621d102b48SJeremy L Thompson 6631d102b48SJeremy L Thompson // Output blocked restriction 6641d102b48SJeremy L Thompson ierr = CeedVectorRestoreArray(lvec, &a); CeedChk(ierr); 6651d102b48SJeremy L Thompson ierr = CeedVectorSetValue(*assembled, 0.0); CeedChk(ierr); 6661d102b48SJeremy L Thompson CeedElemRestriction blkrstr; 667*61dbc9d2Sjeremylt ierr = CeedElemRestrictionCreateBlocked(ceed, imode, numelements, Q, blksize, 6681d102b48SJeremy L Thompson numelements*Q, 6691d102b48SJeremy L Thompson numactivein*numactiveout, 6701d102b48SJeremy L Thompson CEED_MEM_HOST, CEED_COPY_VALUES, 6711d102b48SJeremy L Thompson NULL, &blkrstr); CeedChk(ierr); 672a8d32208Sjeremylt ierr = CeedElemRestrictionApply(blkrstr, CEED_TRANSPOSE, lvec, *assembled, 673a8d32208Sjeremylt request); CeedChk(ierr); 6741d102b48SJeremy L Thompson 6751d102b48SJeremy L Thompson // Cleanup 67642ea3801Sjeremylt for (CeedInt i=0; i<numactivein; i++) { 67742ea3801Sjeremylt ierr = CeedVectorDestroy(&activein[i]); CeedChk(ierr); 67842ea3801Sjeremylt } 6791d102b48SJeremy L Thompson ierr = CeedFree(&activein); CeedChk(ierr); 6801d102b48SJeremy L Thompson ierr = CeedVectorDestroy(&lvec); CeedChk(ierr); 6811d102b48SJeremy L Thompson ierr = CeedElemRestrictionDestroy(&blkrstr); CeedChk(ierr); 6821d102b48SJeremy L Thompson 6834a2e7687Sjeremylt return 0; 6844a2e7687Sjeremylt } 6854a2e7687Sjeremylt 686f10650afSjeremylt //------------------------------------------------------------------------------ 687f10650afSjeremylt // Operator Destroy 688f10650afSjeremylt //------------------------------------------------------------------------------ 689f10650afSjeremylt static int CeedOperatorDestroy_Blocked(CeedOperator op) { 690f10650afSjeremylt int ierr; 691f10650afSjeremylt CeedOperator_Blocked *impl; 692f10650afSjeremylt ierr = CeedOperatorGetData(op, (void *)&impl); CeedChk(ierr); 693f10650afSjeremylt 694f10650afSjeremylt for (CeedInt i=0; i<impl->numein+impl->numeout; i++) { 695f10650afSjeremylt ierr = CeedElemRestrictionDestroy(&impl->blkrestr[i]); CeedChk(ierr); 696f10650afSjeremylt ierr = CeedVectorDestroy(&impl->evecs[i]); CeedChk(ierr); 697f10650afSjeremylt } 698f10650afSjeremylt ierr = CeedFree(&impl->blkrestr); CeedChk(ierr); 699f10650afSjeremylt ierr = CeedFree(&impl->evecs); CeedChk(ierr); 700f10650afSjeremylt ierr = CeedFree(&impl->edata); CeedChk(ierr); 701f10650afSjeremylt ierr = CeedFree(&impl->inputstate); CeedChk(ierr); 702f10650afSjeremylt 703f10650afSjeremylt for (CeedInt i=0; i<impl->numein; i++) { 704f10650afSjeremylt ierr = CeedVectorDestroy(&impl->evecsin[i]); CeedChk(ierr); 705f10650afSjeremylt ierr = CeedVectorDestroy(&impl->qvecsin[i]); CeedChk(ierr); 706f10650afSjeremylt } 707f10650afSjeremylt ierr = CeedFree(&impl->evecsin); CeedChk(ierr); 708f10650afSjeremylt ierr = CeedFree(&impl->qvecsin); CeedChk(ierr); 709f10650afSjeremylt 710f10650afSjeremylt for (CeedInt i=0; i<impl->numeout; i++) { 711f10650afSjeremylt ierr = CeedVectorDestroy(&impl->evecsout[i]); CeedChk(ierr); 712f10650afSjeremylt ierr = CeedVectorDestroy(&impl->qvecsout[i]); CeedChk(ierr); 713f10650afSjeremylt } 714f10650afSjeremylt ierr = CeedFree(&impl->evecsout); CeedChk(ierr); 715f10650afSjeremylt ierr = CeedFree(&impl->qvecsout); CeedChk(ierr); 716f10650afSjeremylt 717f10650afSjeremylt ierr = CeedFree(&impl); CeedChk(ierr); 718f10650afSjeremylt return 0; 719f10650afSjeremylt } 720f10650afSjeremylt 721f10650afSjeremylt //------------------------------------------------------------------------------ 722f10650afSjeremylt // Operator Create 723f10650afSjeremylt //------------------------------------------------------------------------------ 7244a2e7687Sjeremylt int CeedOperatorCreate_Blocked(CeedOperator op) { 7254a2e7687Sjeremylt int ierr; 726fe2413ffSjeremylt Ceed ceed; 727fe2413ffSjeremylt ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 7284ce2993fSjeremylt CeedOperator_Blocked *impl; 7294a2e7687Sjeremylt 7304a2e7687Sjeremylt ierr = CeedCalloc(1, &impl); CeedChk(ierr); 731de686571SJeremy L Thompson ierr = CeedOperatorSetData(op, (void *)&impl); CeedChk(ierr); 732fe2413ffSjeremylt 7331d102b48SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Operator", op, "AssembleLinearQFunction", 7341d102b48SJeremy L Thompson CeedOperatorAssembleLinearQFunction_Blocked); 7351d102b48SJeremy L Thompson CeedChk(ierr); 736cae8b89aSjeremylt ierr = CeedSetBackendFunction(ceed, "Operator", op, "ApplyAdd", 737fe2413ffSjeremylt CeedOperatorApply_Blocked); CeedChk(ierr); 738fe2413ffSjeremylt ierr = CeedSetBackendFunction(ceed, "Operator", op, "Destroy", 739fe2413ffSjeremylt CeedOperatorDestroy_Blocked); CeedChk(ierr); 7404a2e7687Sjeremylt return 0; 7414a2e7687Sjeremylt } 742f10650afSjeremylt //------------------------------------------------------------------------------ 743