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 20*f10650afSjeremylt //------------------------------------------------------------------------------ 21*f10650afSjeremylt // Setup Input/Output Fields 22*f10650afSjeremylt //------------------------------------------------------------------------------ 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; 624ce2993fSjeremylt ierr = CeedElemRestrictionGetNumElements(r, &nelem); CeedChk(ierr); 634ce2993fSjeremylt ierr = CeedElemRestrictionGetElementSize(r, &elemsize); CeedChk(ierr); 648795c945Sjeremylt ierr = CeedElemRestrictionGetNumNodes(r, &nnodes); CeedChk(ierr); 654ce2993fSjeremylt ierr = CeedElemRestrictionGetNumComponents(r, &ncomp); CeedChk(ierr); 664ce2993fSjeremylt ierr = CeedElemRestrictionCreateBlocked(ceed, nelem, elemsize, 678795c945Sjeremylt blksize, nnodes, ncomp, 684a2e7687Sjeremylt CEED_MEM_HOST, CEED_COPY_VALUES, 69aedaa0e5Sjeremylt data->indices, &blkrestr[i+starte]); 704a2e7687Sjeremylt CeedChk(ierr); 71aedaa0e5Sjeremylt ierr = CeedElemRestrictionCreateVector(blkrestr[i+starte], NULL, 7291703d3fSjeremylt &fullevecs[i+starte]); 734a2e7687Sjeremylt CeedChk(ierr); 744a2e7687Sjeremylt } 754a2e7687Sjeremylt 764a2e7687Sjeremylt switch(emode) { 774a2e7687Sjeremylt case CEED_EVAL_NONE: 784d537eeaSYohann ierr = CeedQFunctionFieldGetSize(qffields[i], &size); CeedChk(ierr); 794d537eeaSYohann ierr = CeedVectorCreate(ceed, Q*size*blksize, &qvecs[i]); CeedChk(ierr); 80aedaa0e5Sjeremylt break; 81aedaa0e5Sjeremylt case CEED_EVAL_INTERP: 824d537eeaSYohann ierr = CeedQFunctionFieldGetSize(qffields[i], &size); CeedChk(ierr); 834d1cd9fcSJeremy L Thompson ierr = CeedElemRestrictionGetElementSize(r, &P); 844d1cd9fcSJeremy L Thompson CeedChk(ierr); 854d537eeaSYohann ierr = CeedVectorCreate(ceed, P*size*blksize, &evecs[i]); CeedChk(ierr); 864d537eeaSYohann ierr = CeedVectorCreate(ceed, Q*size*blksize, &qvecs[i]); CeedChk(ierr); 874a2e7687Sjeremylt break; 884a2e7687Sjeremylt case CEED_EVAL_GRAD: 89aedaa0e5Sjeremylt ierr = CeedOperatorFieldGetBasis(opfields[i], &basis); CeedChk(ierr); 904d537eeaSYohann ierr = CeedQFunctionFieldGetSize(qffields[i], &size); CeedChk(ierr); 91d1bcdac9Sjeremylt ierr = CeedBasisGetDimension(basis, &dim); CeedChk(ierr); 924d1cd9fcSJeremy L Thompson ierr = CeedElemRestrictionGetElementSize(r, &P); 934d1cd9fcSJeremy L Thompson CeedChk(ierr); 944d537eeaSYohann ierr = CeedVectorCreate(ceed, P*size/dim*blksize, &evecs[i]); CeedChk(ierr); 954d537eeaSYohann ierr = CeedVectorCreate(ceed, Q*size*blksize, &qvecs[i]); CeedChk(ierr); 964a2e7687Sjeremylt break; 974a2e7687Sjeremylt case CEED_EVAL_WEIGHT: // Only on input fields 98aedaa0e5Sjeremylt ierr = CeedOperatorFieldGetBasis(opfields[i], &basis); CeedChk(ierr); 99aedaa0e5Sjeremylt ierr = CeedVectorCreate(ceed, Q*blksize, &qvecs[i]); CeedChk(ierr); 100d1bcdac9Sjeremylt ierr = CeedBasisApply(basis, blksize, CEED_NOTRANSPOSE, 101a7b7f929Sjeremylt CEED_EVAL_WEIGHT, CEED_VECTOR_NONE, qvecs[i]); 102a7b7f929Sjeremylt CeedChk(ierr); 103aedaa0e5Sjeremylt 1044a2e7687Sjeremylt break; 1054a2e7687Sjeremylt case CEED_EVAL_DIV: 1064d537eeaSYohann break; // Not implemented 1074a2e7687Sjeremylt case CEED_EVAL_CURL: 1084d537eeaSYohann break; // Not implemented 1094a2e7687Sjeremylt } 1104a2e7687Sjeremylt } 1114a2e7687Sjeremylt return 0; 1124a2e7687Sjeremylt } 1134a2e7687Sjeremylt 114*f10650afSjeremylt //------------------------------------------------------------------------------ 115*f10650afSjeremylt // Setup Operator 116*f10650afSjeremylt //------------------------------------------------------------------------------ 1174a2e7687Sjeremylt static int CeedOperatorSetup_Blocked(CeedOperator op) { 1184a2e7687Sjeremylt int ierr; 1194ce2993fSjeremylt bool setupdone; 1204ce2993fSjeremylt ierr = CeedOperatorGetSetupStatus(op, &setupdone); CeedChk(ierr); 1214ce2993fSjeremylt if (setupdone) return 0; 122aedaa0e5Sjeremylt Ceed ceed; 123aedaa0e5Sjeremylt ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 1244ce2993fSjeremylt CeedOperator_Blocked *impl; 1254ce2993fSjeremylt ierr = CeedOperatorGetData(op, (void *)&impl); CeedChk(ierr); 1264ce2993fSjeremylt CeedQFunction qf; 1274ce2993fSjeremylt ierr = CeedOperatorGetQFunction(op, &qf); CeedChk(ierr); 1284ce2993fSjeremylt CeedInt Q, numinputfields, numoutputfields; 1294ce2993fSjeremylt ierr = CeedOperatorGetNumQuadraturePoints(op, &Q); CeedChk(ierr); 13016911fdaSjeremylt ierr = CeedQFunctionGetIdentityStatus(qf, &impl->identityqf); CeedChk(ierr); 1314a2e7687Sjeremylt ierr= CeedQFunctionGetNumArgs(qf, &numinputfields, &numoutputfields); 1324a2e7687Sjeremylt CeedChk(ierr); 133d1bcdac9Sjeremylt CeedOperatorField *opinputfields, *opoutputfields; 134d1bcdac9Sjeremylt ierr = CeedOperatorGetFields(op, &opinputfields, &opoutputfields); 135d1bcdac9Sjeremylt CeedChk(ierr); 136d1bcdac9Sjeremylt CeedQFunctionField *qfinputfields, *qfoutputfields; 137d1bcdac9Sjeremylt ierr = CeedQFunctionGetFields(qf, &qfinputfields, &qfoutputfields); 138d1bcdac9Sjeremylt CeedChk(ierr); 1394a2e7687Sjeremylt 1404a2e7687Sjeremylt // Allocate 141aedaa0e5Sjeremylt ierr = CeedCalloc(numinputfields + numoutputfields, &impl->blkrestr); 1424a2e7687Sjeremylt CeedChk(ierr); 143aedaa0e5Sjeremylt ierr = CeedCalloc(numinputfields + numoutputfields, &impl->evecs); 1444a2e7687Sjeremylt CeedChk(ierr); 145aedaa0e5Sjeremylt ierr = CeedCalloc(numinputfields + numoutputfields, &impl->edata); 1464a2e7687Sjeremylt CeedChk(ierr); 1474a2e7687Sjeremylt 14816c359e6Sjeremylt ierr = CeedCalloc(16, &impl->inputstate); CeedChk(ierr); 14991703d3fSjeremylt ierr = CeedCalloc(16, &impl->evecsin); CeedChk(ierr); 15091703d3fSjeremylt ierr = CeedCalloc(16, &impl->evecsout); CeedChk(ierr); 151aedaa0e5Sjeremylt ierr = CeedCalloc(16, &impl->qvecsin); CeedChk(ierr); 152aedaa0e5Sjeremylt ierr = CeedCalloc(16, &impl->qvecsout); CeedChk(ierr); 1534a2e7687Sjeremylt 154aedaa0e5Sjeremylt impl->numein = numinputfields; impl->numeout = numoutputfields; 155aedaa0e5Sjeremylt 1564a2e7687Sjeremylt // Set up infield and outfield pointer arrays 1574a2e7687Sjeremylt // Infields 158aedaa0e5Sjeremylt ierr = CeedOperatorSetupFields_Blocked(qf, op, 0, impl->blkrestr, 15991703d3fSjeremylt impl->evecs, impl->evecsin, 16091703d3fSjeremylt impl->qvecsin, 0, 161aedaa0e5Sjeremylt numinputfields, Q); 1624a2e7687Sjeremylt CeedChk(ierr); 1634a2e7687Sjeremylt // Outfields 164aedaa0e5Sjeremylt ierr = CeedOperatorSetupFields_Blocked(qf, op, 1, impl->blkrestr, 16591703d3fSjeremylt impl->evecs, impl->evecsout, 16691703d3fSjeremylt impl->qvecsout, numinputfields, 16791703d3fSjeremylt numoutputfields, Q); 1684a2e7687Sjeremylt CeedChk(ierr); 169aedaa0e5Sjeremylt 17016911fdaSjeremylt // Identity QFunctions 17116911fdaSjeremylt if (impl->identityqf) { 17216911fdaSjeremylt CeedEvalMode inmode, outmode; 17316911fdaSjeremylt CeedQFunctionField *infields, *outfields; 17416911fdaSjeremylt ierr = CeedQFunctionGetFields(qf, &infields, &outfields); CeedChk(ierr); 17516911fdaSjeremylt 17616911fdaSjeremylt for (CeedInt i=0; i<numinputfields; i++) { 17716911fdaSjeremylt ierr = CeedQFunctionFieldGetEvalMode(infields[i], &inmode); 17816911fdaSjeremylt CeedChk(ierr); 17916911fdaSjeremylt ierr = CeedQFunctionFieldGetEvalMode(outfields[i], &outmode); 18016911fdaSjeremylt CeedChk(ierr); 18116911fdaSjeremylt 18216911fdaSjeremylt ierr = CeedVectorDestroy(&impl->qvecsout[i]); CeedChk(ierr); 18316911fdaSjeremylt impl->qvecsout[i] = impl->qvecsin[i]; 18455e4cc5bSjeremylt ierr = CeedVectorAddReference(impl->qvecsin[i]); CeedChk(ierr); 18516911fdaSjeremylt } 18616911fdaSjeremylt } 18716911fdaSjeremylt 1884ce2993fSjeremylt ierr = CeedOperatorSetSetupDone(op); CeedChk(ierr); 1894a2e7687Sjeremylt 1904a2e7687Sjeremylt return 0; 1914a2e7687Sjeremylt } 1924a2e7687Sjeremylt 193*f10650afSjeremylt //------------------------------------------------------------------------------ 194*f10650afSjeremylt // Setup Operator Inputs 195*f10650afSjeremylt //------------------------------------------------------------------------------ 1961d102b48SJeremy L Thompson static inline int CeedOperatorSetupInputs_Blocked(CeedInt numinputfields, 1971d102b48SJeremy L Thompson CeedQFunctionField *qfinputfields, CeedOperatorField *opinputfields, 1981d102b48SJeremy L Thompson CeedVector invec, bool skipactive, CeedOperator_Blocked *impl, 19989c6efa4Sjeremylt CeedRequest *request) { 2001d102b48SJeremy L Thompson CeedInt ierr; 201d1bcdac9Sjeremylt CeedEvalMode emode; 202d1bcdac9Sjeremylt CeedVector vec; 2031d102b48SJeremy L Thompson CeedTransposeMode lmode; 20416c359e6Sjeremylt uint64_t state; 2054a2e7687Sjeremylt 2064a2e7687Sjeremylt for (CeedInt i=0; i<numinputfields; i++) { 2071d102b48SJeremy L Thompson // Get input vector 2081d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opinputfields[i], &vec); CeedChk(ierr); 2091d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 2101d102b48SJeremy L Thompson if (skipactive) 2111d102b48SJeremy L Thompson continue; 2121d102b48SJeremy L Thompson else 2131d102b48SJeremy L Thompson vec = invec; 2141d102b48SJeremy L Thompson } 2151d102b48SJeremy L Thompson 216d1bcdac9Sjeremylt ierr = CeedQFunctionFieldGetEvalMode(qfinputfields[i], &emode); 217d1bcdac9Sjeremylt CeedChk(ierr); 2184a2e7687Sjeremylt if (emode == CEED_EVAL_WEIGHT) { // Skip 2194a2e7687Sjeremylt } else { 2204a2e7687Sjeremylt // Restrict 22116c359e6Sjeremylt ierr = CeedVectorGetState(vec, &state); CeedChk(ierr); 22289c6efa4Sjeremylt if (state != impl->inputstate[i] || vec == invec) { 2231d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetLMode(opinputfields[i], &lmode); 2241d102b48SJeremy L Thompson CeedChk(ierr); 2254a2e7687Sjeremylt ierr = CeedElemRestrictionApply(impl->blkrestr[i], CEED_NOTRANSPOSE, 22689c6efa4Sjeremylt lmode, vec, impl->evecs[i], 22789c6efa4Sjeremylt request); CeedChk(ierr); CeedChk(ierr); 22816c359e6Sjeremylt impl->inputstate[i] = state; 22916c359e6Sjeremylt } 2304a2e7687Sjeremylt // Get evec 2314a2e7687Sjeremylt ierr = CeedVectorGetArrayRead(impl->evecs[i], CEED_MEM_HOST, 2324a2e7687Sjeremylt (const CeedScalar **) &impl->edata[i]); 2334a2e7687Sjeremylt CeedChk(ierr); 2344a2e7687Sjeremylt } 2354a2e7687Sjeremylt } 2361d102b48SJeremy L Thompson return 0; 2374a2e7687Sjeremylt } 2384a2e7687Sjeremylt 239*f10650afSjeremylt //------------------------------------------------------------------------------ 240*f10650afSjeremylt // Input Basis Action 241*f10650afSjeremylt //------------------------------------------------------------------------------ 2421d102b48SJeremy L Thompson static inline int CeedOperatorInputBasis_Blocked(CeedInt e, CeedInt Q, 2431d102b48SJeremy L Thompson CeedQFunctionField *qfinputfields, CeedOperatorField *opinputfields, 2441d102b48SJeremy L Thompson CeedInt numinputfields, CeedInt blksize, bool skipactive, 2451d102b48SJeremy L Thompson CeedOperator_Blocked *impl) { 2461d102b48SJeremy L Thompson CeedInt ierr; 2471d102b48SJeremy L Thompson CeedInt dim, elemsize, size; 2481d102b48SJeremy L Thompson CeedElemRestriction Erestrict; 2491d102b48SJeremy L Thompson CeedEvalMode emode; 2501d102b48SJeremy L Thompson CeedBasis basis; 2511d102b48SJeremy L Thompson 2524a2e7687Sjeremylt for (CeedInt i=0; i<numinputfields; i++) { 2531d102b48SJeremy L Thompson // Skip active input 2541d102b48SJeremy L Thompson if (skipactive) { 2551d102b48SJeremy L Thompson CeedVector vec; 2561d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opinputfields[i], &vec); CeedChk(ierr); 2571d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) 2581d102b48SJeremy L Thompson continue; 2591d102b48SJeremy L Thompson } 2601d102b48SJeremy L Thompson 2614d537eeaSYohann // Get elemsize, emode, size 262d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetElemRestriction(opinputfields[i], &Erestrict); 263d1bcdac9Sjeremylt CeedChk(ierr); 264d1bcdac9Sjeremylt ierr = CeedElemRestrictionGetElementSize(Erestrict, &elemsize); 265d1bcdac9Sjeremylt CeedChk(ierr); 266d1bcdac9Sjeremylt ierr = CeedQFunctionFieldGetEvalMode(qfinputfields[i], &emode); 267d1bcdac9Sjeremylt CeedChk(ierr); 2684d537eeaSYohann ierr = CeedQFunctionFieldGetSize(qfinputfields[i], &size); CeedChk(ierr); 2694a2e7687Sjeremylt // Basis action 2704a2e7687Sjeremylt switch(emode) { 2714a2e7687Sjeremylt case CEED_EVAL_NONE: 272aedaa0e5Sjeremylt ierr = CeedVectorSetArray(impl->qvecsin[i], CEED_MEM_HOST, 273aedaa0e5Sjeremylt CEED_USE_POINTER, 2744d537eeaSYohann &impl->edata[i][e*Q*size]); CeedChk(ierr); 2754a2e7687Sjeremylt break; 2764a2e7687Sjeremylt case CEED_EVAL_INTERP: 27789c6efa4Sjeremylt ierr = CeedOperatorFieldGetBasis(opinputfields[i], &basis); CeedChk(ierr); 27891703d3fSjeremylt ierr = CeedVectorSetArray(impl->evecsin[i], CEED_MEM_HOST, 279aedaa0e5Sjeremylt CEED_USE_POINTER, 2804d537eeaSYohann &impl->edata[i][e*elemsize*size]); 2814a2e7687Sjeremylt CeedChk(ierr); 282d1bcdac9Sjeremylt ierr = CeedBasisApply(basis, blksize, CEED_NOTRANSPOSE, 28391703d3fSjeremylt CEED_EVAL_INTERP, impl->evecsin[i], 284aedaa0e5Sjeremylt impl->qvecsin[i]); CeedChk(ierr); 2854a2e7687Sjeremylt break; 2864a2e7687Sjeremylt case CEED_EVAL_GRAD: 28789c6efa4Sjeremylt ierr = CeedOperatorFieldGetBasis(opinputfields[i], &basis); CeedChk(ierr); 2884d537eeaSYohann ierr = CeedBasisGetDimension(basis, &dim); CeedChk(ierr); 28991703d3fSjeremylt ierr = CeedVectorSetArray(impl->evecsin[i], CEED_MEM_HOST, 290aedaa0e5Sjeremylt CEED_USE_POINTER, 2914d537eeaSYohann &impl->edata[i][e*elemsize*size/dim]); 2924a2e7687Sjeremylt CeedChk(ierr); 293d1bcdac9Sjeremylt ierr = CeedBasisApply(basis, blksize, CEED_NOTRANSPOSE, 29491703d3fSjeremylt CEED_EVAL_GRAD, impl->evecsin[i], 295aedaa0e5Sjeremylt impl->qvecsin[i]); CeedChk(ierr); 2964a2e7687Sjeremylt break; 2974a2e7687Sjeremylt case CEED_EVAL_WEIGHT: 2984a2e7687Sjeremylt break; // No action 2994a2e7687Sjeremylt case CEED_EVAL_DIV: 3001d102b48SJeremy L Thompson case CEED_EVAL_CURL: { 3011d102b48SJeremy L Thompson // LCOV_EXCL_START 3021d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetBasis(opinputfields[i], &basis); 3031d102b48SJeremy L Thompson CeedChk(ierr); 3041d102b48SJeremy L Thompson Ceed ceed; 3051d102b48SJeremy L Thompson ierr = CeedBasisGetCeed(basis, &ceed); CeedChk(ierr); 3061d102b48SJeremy L Thompson return CeedError(ceed, 1, "Ceed evaluation mode not implemented"); 3071d102b48SJeremy L Thompson // LCOV_EXCL_STOP 3088c91a0c9SJeremy L Thompson break; // Not implemented 3094a2e7687Sjeremylt } 3104a2e7687Sjeremylt } 31189c6efa4Sjeremylt } 3121d102b48SJeremy L Thompson return 0; 31389c6efa4Sjeremylt } 3144a2e7687Sjeremylt 315*f10650afSjeremylt //------------------------------------------------------------------------------ 316*f10650afSjeremylt // Output Basis Action 317*f10650afSjeremylt //------------------------------------------------------------------------------ 3181d102b48SJeremy L Thompson static inline int CeedOperatorOutputBasis_Blocked(CeedInt e, CeedInt Q, 3191d102b48SJeremy L Thompson CeedQFunctionField *qfoutputfields, CeedOperatorField *opoutputfields, 3201d102b48SJeremy L Thompson CeedInt blksize, CeedInt numinputfields, CeedInt numoutputfields, 3211d102b48SJeremy L Thompson CeedOperator op, CeedOperator_Blocked *impl) { 3221d102b48SJeremy L Thompson CeedInt ierr; 3231d102b48SJeremy L Thompson CeedInt dim, elemsize, size; 3241d102b48SJeremy L Thompson CeedElemRestriction Erestrict; 3251d102b48SJeremy L Thompson CeedEvalMode emode; 3261d102b48SJeremy L Thompson CeedBasis basis; 3271d102b48SJeremy L Thompson 3284a2e7687Sjeremylt for (CeedInt i=0; i<numoutputfields; i++) { 3294d537eeaSYohann // Get elemsize, emode, size 330d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetElemRestriction(opoutputfields[i], &Erestrict); 331d1bcdac9Sjeremylt CeedChk(ierr); 33289c6efa4Sjeremylt ierr = CeedElemRestrictionGetElementSize(Erestrict, &elemsize); 33389c6efa4Sjeremylt CeedChk(ierr); 334d1bcdac9Sjeremylt ierr = CeedQFunctionFieldGetEvalMode(qfoutputfields[i], &emode); 335d1bcdac9Sjeremylt CeedChk(ierr); 3364d537eeaSYohann ierr = CeedQFunctionFieldGetSize(qfoutputfields[i], &size); CeedChk(ierr); 3374a2e7687Sjeremylt // Basis action 3384a2e7687Sjeremylt switch(emode) { 3394a2e7687Sjeremylt case CEED_EVAL_NONE: 3404a2e7687Sjeremylt break; // No action 3414a2e7687Sjeremylt case CEED_EVAL_INTERP: 342d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetBasis(opoutputfields[i], &basis); 343d1bcdac9Sjeremylt CeedChk(ierr); 34489c6efa4Sjeremylt ierr = CeedVectorSetArray(impl->evecsout[i], CEED_MEM_HOST, 34589c6efa4Sjeremylt CEED_USE_POINTER, 3464d537eeaSYohann &impl->edata[i + numinputfields][e*elemsize*size]); 34789c6efa4Sjeremylt CeedChk(ierr); 348aedaa0e5Sjeremylt ierr = CeedBasisApply(basis, blksize, CEED_TRANSPOSE, 349aedaa0e5Sjeremylt CEED_EVAL_INTERP, impl->qvecsout[i], 35091703d3fSjeremylt impl->evecsout[i]); CeedChk(ierr); 3514a2e7687Sjeremylt break; 3524a2e7687Sjeremylt case CEED_EVAL_GRAD: 353d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetBasis(opoutputfields[i], &basis); 354d1bcdac9Sjeremylt CeedChk(ierr); 3554d537eeaSYohann ierr = CeedBasisGetDimension(basis, &dim); CeedChk(ierr); 35689c6efa4Sjeremylt ierr = CeedVectorSetArray(impl->evecsout[i], CEED_MEM_HOST, 35789c6efa4Sjeremylt CEED_USE_POINTER, 3584d537eeaSYohann &impl->edata[i + numinputfields][e*elemsize*size/dim]); 35989c6efa4Sjeremylt CeedChk(ierr); 360d1bcdac9Sjeremylt ierr = CeedBasisApply(basis, blksize, CEED_TRANSPOSE, 361aedaa0e5Sjeremylt CEED_EVAL_GRAD, impl->qvecsout[i], 36291703d3fSjeremylt impl->evecsout[i]); CeedChk(ierr); 3634a2e7687Sjeremylt break; 3644ce2993fSjeremylt case CEED_EVAL_WEIGHT: { 365c042f62fSJeremy L Thompson // LCOV_EXCL_START 3664ce2993fSjeremylt Ceed ceed; 3674ce2993fSjeremylt ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 3681d102b48SJeremy L Thompson return CeedError(ceed, 1, "CEED_EVAL_WEIGHT cannot be an output " 3691d102b48SJeremy L Thompson "evaluation mode"); 370c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 3714a2e7687Sjeremylt break; // Should not occur 3724ce2993fSjeremylt } 3734a2e7687Sjeremylt case CEED_EVAL_DIV: 3741d102b48SJeremy L Thompson case CEED_EVAL_CURL: { 3751d102b48SJeremy L Thompson // LCOV_EXCL_START 3761d102b48SJeremy L Thompson Ceed ceed; 3771d102b48SJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 3781d102b48SJeremy L Thompson return CeedError(ceed, 1, "Ceed evaluation mode not implemented"); 3791d102b48SJeremy L Thompson // LCOV_EXCL_STOP 3808c91a0c9SJeremy L Thompson break; // Not implemented 3814a2e7687Sjeremylt } 38289c6efa4Sjeremylt } 38389c6efa4Sjeremylt } 3841d102b48SJeremy L Thompson return 0; 3851d102b48SJeremy L Thompson } 3861d102b48SJeremy L Thompson 387*f10650afSjeremylt //------------------------------------------------------------------------------ 388*f10650afSjeremylt // Restore Input Vectors 389*f10650afSjeremylt //------------------------------------------------------------------------------ 3901d102b48SJeremy L Thompson static inline int CeedOperatorRestoreInputs_Blocked(CeedInt numinputfields, 3911d102b48SJeremy L Thompson CeedQFunctionField *qfinputfields, CeedOperatorField *opinputfields, 3921d102b48SJeremy L Thompson bool skipactive, CeedOperator_Blocked *impl) { 3931d102b48SJeremy L Thompson CeedInt ierr; 3941d102b48SJeremy L Thompson CeedEvalMode emode; 3951d102b48SJeremy L Thompson 3961d102b48SJeremy L Thompson for (CeedInt i=0; i<numinputfields; i++) { 3971d102b48SJeremy L Thompson // Skip active inputs 3981d102b48SJeremy L Thompson if (skipactive) { 3991d102b48SJeremy L Thompson CeedVector vec; 4001d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opinputfields[i], &vec); CeedChk(ierr); 4011d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) 4021d102b48SJeremy L Thompson continue; 4031d102b48SJeremy L Thompson } 4041d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetEvalMode(qfinputfields[i], &emode); 4051d102b48SJeremy L Thompson CeedChk(ierr); 4061d102b48SJeremy L Thompson if (emode == CEED_EVAL_WEIGHT) { // Skip 4071d102b48SJeremy L Thompson } else { 4081d102b48SJeremy L Thompson ierr = CeedVectorRestoreArrayRead(impl->evecs[i], 4091d102b48SJeremy L Thompson (const CeedScalar **) &impl->edata[i]); 4101d102b48SJeremy L Thompson CeedChk(ierr); 4111d102b48SJeremy L Thompson } 4121d102b48SJeremy L Thompson } 4131d102b48SJeremy L Thompson return 0; 4141d102b48SJeremy L Thompson } 4151d102b48SJeremy L Thompson 416*f10650afSjeremylt //------------------------------------------------------------------------------ 417*f10650afSjeremylt // Operator Apply 418*f10650afSjeremylt //------------------------------------------------------------------------------ 4191d102b48SJeremy L Thompson static int CeedOperatorApply_Blocked(CeedOperator op, CeedVector invec, 4201d102b48SJeremy L Thompson CeedVector outvec, 4211d102b48SJeremy L Thompson CeedRequest *request) { 4221d102b48SJeremy L Thompson int ierr; 4231d102b48SJeremy L Thompson CeedOperator_Blocked *impl; 4241d102b48SJeremy L Thompson ierr = CeedOperatorGetData(op, (void *)&impl); CeedChk(ierr); 4251d102b48SJeremy L Thompson const CeedInt blksize = 8; 4261d102b48SJeremy L Thompson CeedInt Q, numinputfields, numoutputfields, numelements, size; 4271d102b48SJeremy L Thompson ierr = CeedOperatorGetNumElements(op, &numelements); CeedChk(ierr); 4281d102b48SJeremy L Thompson ierr = CeedOperatorGetNumQuadraturePoints(op, &Q); CeedChk(ierr); 4291d102b48SJeremy L Thompson CeedInt nblks = (numelements/blksize) + !!(numelements%blksize); 4301d102b48SJeremy L Thompson CeedQFunction qf; 4311d102b48SJeremy L Thompson ierr = CeedOperatorGetQFunction(op, &qf); CeedChk(ierr); 4321d102b48SJeremy L Thompson ierr= CeedQFunctionGetNumArgs(qf, &numinputfields, &numoutputfields); 4331d102b48SJeremy L Thompson CeedChk(ierr); 4341d102b48SJeremy L Thompson CeedTransposeMode lmode; 4351d102b48SJeremy L Thompson CeedOperatorField *opinputfields, *opoutputfields; 4361d102b48SJeremy L Thompson ierr = CeedOperatorGetFields(op, &opinputfields, &opoutputfields); 4371d102b48SJeremy L Thompson CeedChk(ierr); 4381d102b48SJeremy L Thompson CeedQFunctionField *qfinputfields, *qfoutputfields; 4391d102b48SJeremy L Thompson ierr = CeedQFunctionGetFields(qf, &qfinputfields, &qfoutputfields); 4401d102b48SJeremy L Thompson CeedChk(ierr); 4411d102b48SJeremy L Thompson CeedEvalMode emode; 4421d102b48SJeremy L Thompson CeedVector vec; 4431d102b48SJeremy L Thompson 4441d102b48SJeremy L Thompson // Setup 4451d102b48SJeremy L Thompson ierr = CeedOperatorSetup_Blocked(op); CeedChk(ierr); 4461d102b48SJeremy L Thompson 4471d102b48SJeremy L Thompson // Input Evecs and Restriction 4481d102b48SJeremy L Thompson ierr = CeedOperatorSetupInputs_Blocked(numinputfields, qfinputfields, 4497f823360Sjeremylt opinputfields, invec, false, impl, 4507f823360Sjeremylt request); CeedChk(ierr); 4511d102b48SJeremy L Thompson 4521d102b48SJeremy L Thompson // Output Evecs 4531d102b48SJeremy L Thompson for (CeedInt i=0; i<numoutputfields; i++) { 4541d102b48SJeremy L Thompson ierr = CeedVectorGetArray(impl->evecs[i+impl->numein], CEED_MEM_HOST, 4551d102b48SJeremy L Thompson &impl->edata[i + numinputfields]); CeedChk(ierr); 4561d102b48SJeremy L Thompson } 4571d102b48SJeremy L Thompson 4581d102b48SJeremy L Thompson // Loop through elements 4591d102b48SJeremy L Thompson for (CeedInt e=0; e<nblks*blksize; e+=blksize) { 4601d102b48SJeremy L Thompson // Output pointers 4611d102b48SJeremy L Thompson for (CeedInt i=0; i<numoutputfields; i++) { 4621d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetEvalMode(qfoutputfields[i], &emode); 4631d102b48SJeremy L Thompson CeedChk(ierr); 4641d102b48SJeremy L Thompson if (emode == CEED_EVAL_NONE) { 4651d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetSize(qfoutputfields[i], &size); 4661d102b48SJeremy L Thompson CeedChk(ierr); 4671d102b48SJeremy L Thompson ierr = CeedVectorSetArray(impl->qvecsout[i], CEED_MEM_HOST, 4681d102b48SJeremy L Thompson CEED_USE_POINTER, 4691d102b48SJeremy L Thompson &impl->edata[i + numinputfields][e*Q*size]); 4701d102b48SJeremy L Thompson CeedChk(ierr); 4711d102b48SJeremy L Thompson } 4721d102b48SJeremy L Thompson } 4731d102b48SJeremy L Thompson 47416911fdaSjeremylt // Input basis apply 47516911fdaSjeremylt ierr = CeedOperatorInputBasis_Blocked(e, Q, qfinputfields, opinputfields, 47616911fdaSjeremylt numinputfields, blksize, false, impl); 47716911fdaSjeremylt CeedChk(ierr); 47816911fdaSjeremylt 4791d102b48SJeremy L Thompson // Q function 48016911fdaSjeremylt if (!impl->identityqf) { 4811d102b48SJeremy L Thompson ierr = CeedQFunctionApply(qf, Q*blksize, impl->qvecsin, impl->qvecsout); 4821d102b48SJeremy L Thompson CeedChk(ierr); 48316911fdaSjeremylt } 4841d102b48SJeremy L Thompson 4851d102b48SJeremy L Thompson // Output basis apply 4861d102b48SJeremy L Thompson ierr = CeedOperatorOutputBasis_Blocked(e, Q, qfoutputfields, opoutputfields, 4877f823360Sjeremylt blksize, numinputfields, 4887f823360Sjeremylt numoutputfields, op, impl); 4891d102b48SJeremy L Thompson CeedChk(ierr); 4901d102b48SJeremy L Thompson } 49189c6efa4Sjeremylt 49289c6efa4Sjeremylt // Output restriction 49389c6efa4Sjeremylt for (CeedInt i=0; i<numoutputfields; i++) { 49489c6efa4Sjeremylt // Restore evec 49589c6efa4Sjeremylt ierr = CeedVectorRestoreArray(impl->evecs[i+impl->numein], 49689c6efa4Sjeremylt &impl->edata[i + numinputfields]); CeedChk(ierr); 497d1bcdac9Sjeremylt // Get output vector 498d1bcdac9Sjeremylt ierr = CeedOperatorFieldGetVector(opoutputfields[i], &vec); CeedChk(ierr); 49989c6efa4Sjeremylt // Active 500d1bcdac9Sjeremylt if (vec == CEED_VECTOR_ACTIVE) 501d1bcdac9Sjeremylt vec = outvec; 5024a2e7687Sjeremylt // Restrict 50389c6efa4Sjeremylt ierr = CeedOperatorFieldGetLMode(opoutputfields[i], &lmode); CeedChk(ierr); 50489c6efa4Sjeremylt ierr = CeedElemRestrictionApply(impl->blkrestr[i+impl->numein], CEED_TRANSPOSE, 50589c6efa4Sjeremylt lmode, impl->evecs[i+impl->numein], vec, 50689c6efa4Sjeremylt request); CeedChk(ierr); 50789c6efa4Sjeremylt 5084a2e7687Sjeremylt } 5094a2e7687Sjeremylt 5104a2e7687Sjeremylt // Restore input arrays 5111d102b48SJeremy L Thompson ierr = CeedOperatorRestoreInputs_Blocked(numinputfields, qfinputfields, 5127f823360Sjeremylt opinputfields, false, impl); CeedChk(ierr); 5131d102b48SJeremy L Thompson 5141d102b48SJeremy L Thompson return 0; 5151d102b48SJeremy L Thompson } 5161d102b48SJeremy L Thompson 517*f10650afSjeremylt //------------------------------------------------------------------------------ 5181d102b48SJeremy L Thompson // Assemble Linear QFunction 519*f10650afSjeremylt //------------------------------------------------------------------------------ 5201d102b48SJeremy L Thompson static int CeedOperatorAssembleLinearQFunction_Blocked(CeedOperator op, 5211d102b48SJeremy L Thompson CeedVector *assembled, CeedElemRestriction *rstr, CeedRequest *request) { 5221d102b48SJeremy L Thompson int ierr; 5231d102b48SJeremy L Thompson CeedOperator_Blocked *impl; 5241d102b48SJeremy L Thompson ierr = CeedOperatorGetData(op, (void *)&impl); CeedChk(ierr); 5251d102b48SJeremy L Thompson const CeedInt blksize = 8; 5261d102b48SJeremy L Thompson CeedInt Q, numinputfields, numoutputfields, numelements, size; 5271d102b48SJeremy L Thompson ierr = CeedOperatorGetNumElements(op, &numelements); CeedChk(ierr); 5281d102b48SJeremy L Thompson ierr = CeedOperatorGetNumQuadraturePoints(op, &Q); CeedChk(ierr); 5291d102b48SJeremy L Thompson CeedInt nblks = (numelements/blksize) + !!(numelements%blksize); 5301d102b48SJeremy L Thompson CeedQFunction qf; 5311d102b48SJeremy L Thompson ierr = CeedOperatorGetQFunction(op, &qf); CeedChk(ierr); 5321d102b48SJeremy L Thompson ierr= CeedQFunctionGetNumArgs(qf, &numinputfields, &numoutputfields); 5331d102b48SJeremy L Thompson CeedChk(ierr); 5341d102b48SJeremy L Thompson CeedOperatorField *opinputfields, *opoutputfields; 5351d102b48SJeremy L Thompson ierr = CeedOperatorGetFields(op, &opinputfields, &opoutputfields); 5361d102b48SJeremy L Thompson CeedChk(ierr); 5371d102b48SJeremy L Thompson CeedQFunctionField *qfinputfields, *qfoutputfields; 5381d102b48SJeremy L Thompson ierr = CeedQFunctionGetFields(qf, &qfinputfields, &qfoutputfields); 5391d102b48SJeremy L Thompson CeedChk(ierr); 5401d102b48SJeremy L Thompson CeedVector vec, lvec; 5411d102b48SJeremy L Thompson CeedInt numactivein = 0, numactiveout = 0; 54242ea3801Sjeremylt CeedVector *activein = NULL; 5431d102b48SJeremy L Thompson CeedScalar *a, *tmp; 5441d102b48SJeremy L Thompson Ceed ceed; 5451d102b48SJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 5461d102b48SJeremy L Thompson 5471d102b48SJeremy L Thompson // Setup 5481d102b48SJeremy L Thompson ierr = CeedOperatorSetup_Blocked(op); CeedChk(ierr); 5491d102b48SJeremy L Thompson 55016911fdaSjeremylt // Check for identity 55116911fdaSjeremylt if (impl->identityqf) 55216911fdaSjeremylt // LCOV_EXCL_START 55367db23e4Sjeremylt return CeedError(ceed, 1, "Assembling identity qfunctions not supported"); 55416911fdaSjeremylt // LCOV_EXCL_STOP 55516911fdaSjeremylt 5561d102b48SJeremy L Thompson // Input Evecs and Restriction 5571d102b48SJeremy L Thompson ierr = CeedOperatorSetupInputs_Blocked(numinputfields, qfinputfields, 5581d102b48SJeremy L Thompson opinputfields, NULL, true, impl, 5591d102b48SJeremy L Thompson request); CeedChk(ierr); 5601d102b48SJeremy L Thompson 5611d102b48SJeremy L Thompson // Count number of active input fields 5624a2e7687Sjeremylt for (CeedInt i=0; i<numinputfields; i++) { 5631d102b48SJeremy L Thompson // Get input vector 5641d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opinputfields[i], &vec); CeedChk(ierr); 5651d102b48SJeremy L Thompson // Check if active input 5661d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 5671d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetSize(qfinputfields[i], &size); CeedChk(ierr); 5681d102b48SJeremy L Thompson ierr = CeedVectorSetValue(impl->qvecsin[i], 0.0); CeedChk(ierr); 5691d102b48SJeremy L Thompson ierr = CeedVectorGetArray(impl->qvecsin[i], CEED_MEM_HOST, &tmp); 570d1bcdac9Sjeremylt CeedChk(ierr); 5711d102b48SJeremy L Thompson ierr = CeedRealloc(numactivein + size, &activein); CeedChk(ierr); 5721d102b48SJeremy L Thompson for (CeedInt field=0; field<size; field++) { 57342ea3801Sjeremylt ierr = CeedVectorCreate(ceed, Q*blksize, &activein[numactivein+field]); 57442ea3801Sjeremylt CeedChk(ierr); 57542ea3801Sjeremylt ierr = CeedVectorSetArray(activein[numactivein+field], CEED_MEM_HOST, 57642ea3801Sjeremylt CEED_USE_POINTER, &tmp[field*Q*blksize]); 577112e3f70Sjeremylt CeedChk(ierr); 5781d102b48SJeremy L Thompson } 5791d102b48SJeremy L Thompson numactivein += size; 5801d102b48SJeremy L Thompson ierr = CeedVectorRestoreArray(impl->qvecsin[i], &tmp); CeedChk(ierr); 5811d102b48SJeremy L Thompson } 5821d102b48SJeremy L Thompson } 5831d102b48SJeremy L Thompson 5841d102b48SJeremy L Thompson // Count number of active output fields 5851d102b48SJeremy L Thompson for (CeedInt i=0; i<numoutputfields; i++) { 5861d102b48SJeremy L Thompson // Get output vector 5871d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opoutputfields[i], &vec); CeedChk(ierr); 5881d102b48SJeremy L Thompson // Check if active output 5891d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 5901d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetSize(qfoutputfields[i], &size); CeedChk(ierr); 5911d102b48SJeremy L Thompson numactiveout += size; 5921d102b48SJeremy L Thompson } 5931d102b48SJeremy L Thompson } 5941d102b48SJeremy L Thompson 5951d102b48SJeremy L Thompson // Check sizes 5961d102b48SJeremy L Thompson if (!numactivein || !numactiveout) 5971d102b48SJeremy L Thompson // LCOV_EXCL_START 5981d102b48SJeremy L Thompson return CeedError(ceed, 1, "Cannot assemble QFunction without active inputs " 5991d102b48SJeremy L Thompson "and outputs"); 6001d102b48SJeremy L Thompson // LCOV_EXCL_STOP 6011d102b48SJeremy L Thompson 6021d102b48SJeremy L Thompson // Setup lvec 6031d102b48SJeremy L Thompson ierr = CeedVectorCreate(ceed, nblks*blksize*Q*numactivein*numactiveout, 6041d102b48SJeremy L Thompson &lvec); CeedChk(ierr); 6051d102b48SJeremy L Thompson ierr = CeedVectorGetArray(lvec, CEED_MEM_HOST, &a); CeedChk(ierr); 6061d102b48SJeremy L Thompson 6071d102b48SJeremy L Thompson // Create output restriction 6081d102b48SJeremy L Thompson ierr = CeedElemRestrictionCreateIdentity(ceed, numelements, Q, 6097f823360Sjeremylt numelements*Q, numactivein*numactiveout, rstr); CeedChk(ierr); 6101d102b48SJeremy L Thompson // Create assembled vector 6111d102b48SJeremy L Thompson ierr = CeedVectorCreate(ceed, numelements*Q*numactivein*numactiveout, 6121d102b48SJeremy L Thompson assembled); CeedChk(ierr); 6131d102b48SJeremy L Thompson 6141d102b48SJeremy L Thompson // Loop through elements 6151d102b48SJeremy L Thompson for (CeedInt e=0; e<nblks*blksize; e+=blksize) { 6161d102b48SJeremy L Thompson // Input basis apply 6171d102b48SJeremy L Thompson ierr = CeedOperatorInputBasis_Blocked(e, Q, qfinputfields, opinputfields, 6181d102b48SJeremy L Thompson numinputfields, blksize, true, impl); 6191d102b48SJeremy L Thompson CeedChk(ierr); 6201d102b48SJeremy L Thompson 6211d102b48SJeremy L Thompson // Assemble QFunction 6221d102b48SJeremy L Thompson for (CeedInt in=0; in<numactivein; in++) { 6231d102b48SJeremy L Thompson // Set Inputs 62442ea3801Sjeremylt ierr = CeedVectorSetValue(activein[in], 1.0); CeedChk(ierr); 62542ea3801Sjeremylt if (numactivein > 1) { 62642ea3801Sjeremylt ierr = CeedVectorSetValue(activein[(in+numactivein-1)%numactivein], 62742ea3801Sjeremylt 0.0); CeedChk(ierr); 62842ea3801Sjeremylt } 6291d102b48SJeremy L Thompson // Set Outputs 6301d102b48SJeremy L Thompson for (CeedInt out=0; out<numoutputfields; out++) { 6311d102b48SJeremy L Thompson // Get output vector 6321d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opoutputfields[out], &vec); 6331d102b48SJeremy L Thompson CeedChk(ierr); 6341d102b48SJeremy L Thompson // Check if active output 6351d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 6361d102b48SJeremy L Thompson CeedVectorSetArray(impl->qvecsout[out], CEED_MEM_HOST, 6371d102b48SJeremy L Thompson CEED_USE_POINTER, a); CeedChk(ierr); 6381d102b48SJeremy L Thompson ierr = CeedQFunctionFieldGetSize(qfoutputfields[out], &size); 6391d102b48SJeremy L Thompson CeedChk(ierr); 6401d102b48SJeremy L Thompson a += size*Q*blksize; // Advance the pointer by the size of the output 6411d102b48SJeremy L Thompson } 6421d102b48SJeremy L Thompson } 6431d102b48SJeremy L Thompson // Apply QFunction 6441d102b48SJeremy L Thompson ierr = CeedQFunctionApply(qf, Q*blksize, impl->qvecsin, impl->qvecsout); 645d1bcdac9Sjeremylt CeedChk(ierr); 6464a2e7687Sjeremylt } 6474a2e7687Sjeremylt } 6484a2e7687Sjeremylt 6491d102b48SJeremy L Thompson // Un-set output Qvecs to prevent accidental overwrite of Assembled 6501d102b48SJeremy L Thompson for (CeedInt out=0; out<numoutputfields; out++) { 6511d102b48SJeremy L Thompson // Get output vector 6521d102b48SJeremy L Thompson ierr = CeedOperatorFieldGetVector(opoutputfields[out], &vec); 6531d102b48SJeremy L Thompson CeedChk(ierr); 6541d102b48SJeremy L Thompson // Check if active output 6551d102b48SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 6561d102b48SJeremy L Thompson CeedVectorSetArray(impl->qvecsout[out], CEED_MEM_HOST, CEED_COPY_VALUES, 6571d102b48SJeremy L Thompson NULL); CeedChk(ierr); 6581d102b48SJeremy L Thompson } 6591d102b48SJeremy L Thompson } 6601d102b48SJeremy L Thompson 6611d102b48SJeremy L Thompson // Restore input arrays 6621d102b48SJeremy L Thompson ierr = CeedOperatorRestoreInputs_Blocked(numinputfields, qfinputfields, 6637f823360Sjeremylt opinputfields, true, impl); CeedChk(ierr); 6641d102b48SJeremy L Thompson 6651d102b48SJeremy L Thompson // Output blocked restriction 6661d102b48SJeremy L Thompson ierr = CeedVectorRestoreArray(lvec, &a); CeedChk(ierr); 6671d102b48SJeremy L Thompson ierr = CeedVectorSetValue(*assembled, 0.0); CeedChk(ierr); 6681d102b48SJeremy L Thompson CeedElemRestriction blkrstr; 6691d102b48SJeremy L Thompson ierr = CeedElemRestrictionCreateBlocked(ceed, numelements, Q, blksize, 6701d102b48SJeremy L Thompson numelements*Q, 6711d102b48SJeremy L Thompson numactivein*numactiveout, 6721d102b48SJeremy L Thompson CEED_MEM_HOST, CEED_COPY_VALUES, 6731d102b48SJeremy L Thompson NULL, &blkrstr); CeedChk(ierr); 6741d102b48SJeremy L Thompson ierr = CeedElemRestrictionApply(blkrstr, CEED_TRANSPOSE, CEED_NOTRANSPOSE, 6751d102b48SJeremy L Thompson lvec, *assembled, request); CeedChk(ierr); 6761d102b48SJeremy L Thompson 6771d102b48SJeremy L Thompson // Cleanup 67842ea3801Sjeremylt for (CeedInt i=0; i<numactivein; i++) { 67942ea3801Sjeremylt ierr = CeedVectorDestroy(&activein[i]); CeedChk(ierr); 68042ea3801Sjeremylt } 6811d102b48SJeremy L Thompson ierr = CeedFree(&activein); CeedChk(ierr); 6821d102b48SJeremy L Thompson ierr = CeedVectorDestroy(&lvec); CeedChk(ierr); 6831d102b48SJeremy L Thompson ierr = CeedElemRestrictionDestroy(&blkrstr); CeedChk(ierr); 6841d102b48SJeremy L Thompson 6854a2e7687Sjeremylt return 0; 6864a2e7687Sjeremylt } 6874a2e7687Sjeremylt 688*f10650afSjeremylt //------------------------------------------------------------------------------ 689*f10650afSjeremylt // Operator Destroy 690*f10650afSjeremylt //------------------------------------------------------------------------------ 691*f10650afSjeremylt static int CeedOperatorDestroy_Blocked(CeedOperator op) { 692*f10650afSjeremylt int ierr; 693*f10650afSjeremylt CeedOperator_Blocked *impl; 694*f10650afSjeremylt ierr = CeedOperatorGetData(op, (void *)&impl); CeedChk(ierr); 695*f10650afSjeremylt 696*f10650afSjeremylt for (CeedInt i=0; i<impl->numein+impl->numeout; i++) { 697*f10650afSjeremylt ierr = CeedElemRestrictionDestroy(&impl->blkrestr[i]); CeedChk(ierr); 698*f10650afSjeremylt ierr = CeedVectorDestroy(&impl->evecs[i]); CeedChk(ierr); 699*f10650afSjeremylt } 700*f10650afSjeremylt ierr = CeedFree(&impl->blkrestr); CeedChk(ierr); 701*f10650afSjeremylt ierr = CeedFree(&impl->evecs); CeedChk(ierr); 702*f10650afSjeremylt ierr = CeedFree(&impl->edata); CeedChk(ierr); 703*f10650afSjeremylt ierr = CeedFree(&impl->inputstate); CeedChk(ierr); 704*f10650afSjeremylt 705*f10650afSjeremylt for (CeedInt i=0; i<impl->numein; i++) { 706*f10650afSjeremylt ierr = CeedVectorDestroy(&impl->evecsin[i]); CeedChk(ierr); 707*f10650afSjeremylt ierr = CeedVectorDestroy(&impl->qvecsin[i]); CeedChk(ierr); 708*f10650afSjeremylt } 709*f10650afSjeremylt ierr = CeedFree(&impl->evecsin); CeedChk(ierr); 710*f10650afSjeremylt ierr = CeedFree(&impl->qvecsin); CeedChk(ierr); 711*f10650afSjeremylt 712*f10650afSjeremylt for (CeedInt i=0; i<impl->numeout; i++) { 713*f10650afSjeremylt ierr = CeedVectorDestroy(&impl->evecsout[i]); CeedChk(ierr); 714*f10650afSjeremylt ierr = CeedVectorDestroy(&impl->qvecsout[i]); CeedChk(ierr); 715*f10650afSjeremylt } 716*f10650afSjeremylt ierr = CeedFree(&impl->evecsout); CeedChk(ierr); 717*f10650afSjeremylt ierr = CeedFree(&impl->qvecsout); CeedChk(ierr); 718*f10650afSjeremylt 719*f10650afSjeremylt ierr = CeedFree(&impl); CeedChk(ierr); 720*f10650afSjeremylt return 0; 721*f10650afSjeremylt } 722*f10650afSjeremylt 723*f10650afSjeremylt //------------------------------------------------------------------------------ 724*f10650afSjeremylt // Operator Create 725*f10650afSjeremylt //------------------------------------------------------------------------------ 7264a2e7687Sjeremylt int CeedOperatorCreate_Blocked(CeedOperator op) { 7274a2e7687Sjeremylt int ierr; 728fe2413ffSjeremylt Ceed ceed; 729fe2413ffSjeremylt ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 7304ce2993fSjeremylt CeedOperator_Blocked *impl; 7314a2e7687Sjeremylt 7324a2e7687Sjeremylt ierr = CeedCalloc(1, &impl); CeedChk(ierr); 733de686571SJeremy L Thompson ierr = CeedOperatorSetData(op, (void *)&impl); CeedChk(ierr); 734fe2413ffSjeremylt 7351d102b48SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "Operator", op, "AssembleLinearQFunction", 7361d102b48SJeremy L Thompson CeedOperatorAssembleLinearQFunction_Blocked); 7371d102b48SJeremy L Thompson CeedChk(ierr); 738cae8b89aSjeremylt ierr = CeedSetBackendFunction(ceed, "Operator", op, "ApplyAdd", 739fe2413ffSjeremylt CeedOperatorApply_Blocked); CeedChk(ierr); 740fe2413ffSjeremylt ierr = CeedSetBackendFunction(ceed, "Operator", op, "Destroy", 741fe2413ffSjeremylt CeedOperatorDestroy_Blocked); CeedChk(ierr); 7424a2e7687Sjeremylt return 0; 7434a2e7687Sjeremylt } 744*f10650afSjeremylt //------------------------------------------------------------------------------ 745