1*21617c04Sjeremylt // Copyright (c) 2017-2018, Lawrence Livermore National Security, LLC. 2*21617c04Sjeremylt // Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707. 3*21617c04Sjeremylt // All Rights reserved. See files LICENSE and NOTICE for details. 4*21617c04Sjeremylt // 5*21617c04Sjeremylt // This file is part of CEED, a collection of benchmarks, miniapps, software 6*21617c04Sjeremylt // libraries and APIs for efficient high-order finite element and spectral 7*21617c04Sjeremylt // element discretizations for exascale applications. For more information and 8*21617c04Sjeremylt // source code availability see http://github.com/ceed. 9*21617c04Sjeremylt // 10*21617c04Sjeremylt // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 11*21617c04Sjeremylt // a collaborative effort of two U.S. Department of Energy organizations (Office 12*21617c04Sjeremylt // of Science and the National Nuclear Security Administration) responsible for 13*21617c04Sjeremylt // the planning and preparation of a capable exascale ecosystem, including 14*21617c04Sjeremylt // software, applications, hardware, advanced system engineering and early 15*21617c04Sjeremylt // testbed platforms, in support of the nation's exascale computing imperative. 16*21617c04Sjeremylt 17*21617c04Sjeremylt #include <ceed-impl.h> 18*21617c04Sjeremylt #include <string.h> 19*21617c04Sjeremylt #include "ceed-ref.h" 20*21617c04Sjeremylt 21*21617c04Sjeremylt static int CeedOperatorDestroy_Ref(CeedOperator op) { 22*21617c04Sjeremylt CeedOperator_Ref *impl = op->data; 23*21617c04Sjeremylt int ierr; 24*21617c04Sjeremylt 25*21617c04Sjeremylt ierr = CeedVectorDestroy(&impl->etmp); CeedChk(ierr); 26*21617c04Sjeremylt ierr = CeedVectorDestroy(&impl->qdata); CeedChk(ierr); 27*21617c04Sjeremylt ierr = CeedFree(&op->data); CeedChk(ierr); 28*21617c04Sjeremylt return 0; 29*21617c04Sjeremylt } 30*21617c04Sjeremylt 31*21617c04Sjeremylt static int CeedOperatorApply_Ref(CeedOperator op, CeedVector qdata, 32*21617c04Sjeremylt CeedVector ustate, 33*21617c04Sjeremylt CeedVector residual, CeedRequest *request) { 34*21617c04Sjeremylt CeedOperator_Ref *impl = op->data; 35*21617c04Sjeremylt CeedVector etmp; 36*21617c04Sjeremylt CeedInt Q; 37*21617c04Sjeremylt const CeedInt nc = op->basis->ndof, dim = op->basis->dim; 38*21617c04Sjeremylt CeedScalar *Eu; 39*21617c04Sjeremylt char *qd; 40*21617c04Sjeremylt int ierr; 41*21617c04Sjeremylt CeedTransposeMode lmode = CEED_NOTRANSPOSE; 42*21617c04Sjeremylt 43*21617c04Sjeremylt if (!impl->etmp) { 44*21617c04Sjeremylt ierr = CeedVectorCreate(op->ceed, 45*21617c04Sjeremylt nc * op->Erestrict->nelem * op->Erestrict->elemsize, 46*21617c04Sjeremylt &impl->etmp); CeedChk(ierr); 47*21617c04Sjeremylt // etmp is allocated when CeedVectorGetArray is called below 48*21617c04Sjeremylt } 49*21617c04Sjeremylt etmp = impl->etmp; 50*21617c04Sjeremylt if (op->qf->inmode & ~CEED_EVAL_WEIGHT) { 51*21617c04Sjeremylt ierr = CeedElemRestrictionApply(op->Erestrict, CEED_NOTRANSPOSE, 52*21617c04Sjeremylt nc, lmode, ustate, etmp, 53*21617c04Sjeremylt CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 54*21617c04Sjeremylt } 55*21617c04Sjeremylt ierr = CeedBasisGetNumQuadraturePoints(op->basis, &Q); CeedChk(ierr); 56*21617c04Sjeremylt ierr = CeedVectorGetArray(etmp, CEED_MEM_HOST, &Eu); CeedChk(ierr); 57*21617c04Sjeremylt ierr = CeedVectorGetArray(qdata, CEED_MEM_HOST, (CeedScalar**)&qd); 58*21617c04Sjeremylt CeedChk(ierr); 59*21617c04Sjeremylt for (CeedInt e=0; e<op->Erestrict->nelem; e++) { 60*21617c04Sjeremylt CeedScalar BEu[Q*nc*(dim+2)], BEv[Q*nc*(dim+2)], *out[5] = {0,0,0,0,0}; 61*21617c04Sjeremylt const CeedScalar *in[5] = {0,0,0,0,0}; 62*21617c04Sjeremylt // TODO: quadrature weights can be computed just once 63*21617c04Sjeremylt ierr = CeedBasisApply(op->basis, CEED_NOTRANSPOSE, op->qf->inmode, 64*21617c04Sjeremylt &Eu[e*op->Erestrict->elemsize*nc], BEu); 65*21617c04Sjeremylt CeedChk(ierr); 66*21617c04Sjeremylt CeedScalar *u_ptr = BEu, *v_ptr = BEv; 67*21617c04Sjeremylt if (op->qf->inmode & CEED_EVAL_INTERP) { in[0] = u_ptr; u_ptr += Q*nc; } 68*21617c04Sjeremylt if (op->qf->inmode & CEED_EVAL_GRAD) { in[1] = u_ptr; u_ptr += Q*nc*dim; } 69*21617c04Sjeremylt if (op->qf->inmode & CEED_EVAL_WEIGHT) { in[4] = u_ptr; u_ptr += Q; } 70*21617c04Sjeremylt if (op->qf->outmode & CEED_EVAL_INTERP) { out[0] = v_ptr; v_ptr += Q*nc; } 71*21617c04Sjeremylt if (op->qf->outmode & CEED_EVAL_GRAD) { out[1] = v_ptr; v_ptr += Q*nc*dim; } 72*21617c04Sjeremylt ierr = CeedQFunctionApply(op->qf, &qd[e*Q*op->qf->qdatasize], Q, in, out); 73*21617c04Sjeremylt CeedChk(ierr); 74*21617c04Sjeremylt ierr = CeedBasisApply(op->basis, CEED_TRANSPOSE, op->qf->outmode, BEv, 75*21617c04Sjeremylt &Eu[e*op->Erestrict->elemsize*nc]); 76*21617c04Sjeremylt CeedChk(ierr); 77*21617c04Sjeremylt } 78*21617c04Sjeremylt ierr = CeedVectorRestoreArray(etmp, &Eu); CeedChk(ierr); 79*21617c04Sjeremylt ierr = CeedVectorRestoreArray(qdata, (CeedScalar**)&qd); CeedChk(ierr); 80*21617c04Sjeremylt if (residual) { 81*21617c04Sjeremylt CeedScalar *res; 82*21617c04Sjeremylt ierr = CeedVectorGetArray(residual, CEED_MEM_HOST, &res); CeedChk(ierr); 83*21617c04Sjeremylt for (int i = 0; i < residual->length; i++) 84*21617c04Sjeremylt res[i] = (CeedScalar)0; 85*21617c04Sjeremylt ierr = CeedElemRestrictionApply(op->Erestrict, CEED_TRANSPOSE, 86*21617c04Sjeremylt nc, lmode, etmp, residual, 87*21617c04Sjeremylt CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 88*21617c04Sjeremylt ierr = CeedVectorRestoreArray(residual, &res); CeedChk(ierr); 89*21617c04Sjeremylt } 90*21617c04Sjeremylt if (request != CEED_REQUEST_IMMEDIATE && request != CEED_REQUEST_ORDERED) 91*21617c04Sjeremylt *request = NULL; 92*21617c04Sjeremylt return 0; 93*21617c04Sjeremylt } 94*21617c04Sjeremylt 95*21617c04Sjeremylt static int CeedOperatorGetQData_Ref(CeedOperator op, CeedVector *qdata) { 96*21617c04Sjeremylt CeedOperator_Ref *impl = op->data; 97*21617c04Sjeremylt int ierr; 98*21617c04Sjeremylt 99*21617c04Sjeremylt if (!impl->qdata) { 100*21617c04Sjeremylt CeedInt Q; 101*21617c04Sjeremylt ierr = CeedBasisGetNumQuadraturePoints(op->basis, &Q); CeedChk(ierr); 102*21617c04Sjeremylt ierr = CeedVectorCreate(op->ceed, 103*21617c04Sjeremylt op->Erestrict->nelem * Q 104*21617c04Sjeremylt * op->qf->qdatasize / sizeof(CeedScalar), 105*21617c04Sjeremylt &impl->qdata); CeedChk(ierr); 106*21617c04Sjeremylt } 107*21617c04Sjeremylt *qdata = impl->qdata; 108*21617c04Sjeremylt return 0; 109*21617c04Sjeremylt } 110*21617c04Sjeremylt 111*21617c04Sjeremylt int CeedOperatorCreate_Ref(CeedOperator op) { 112*21617c04Sjeremylt CeedOperator_Ref *impl; 113*21617c04Sjeremylt int ierr; 114*21617c04Sjeremylt 115*21617c04Sjeremylt ierr = CeedCalloc(1, &impl); CeedChk(ierr); 116*21617c04Sjeremylt op->data = impl; 117*21617c04Sjeremylt op->Destroy = CeedOperatorDestroy_Ref; 118*21617c04Sjeremylt op->Apply = CeedOperatorApply_Ref; 119*21617c04Sjeremylt op->GetQData = CeedOperatorGetQData_Ref; 120*21617c04Sjeremylt return 0; 121*21617c04Sjeremylt } 122