xref: /libCEED/rust/libceed-sys/c-src/backends/ref/ceed-ref-operator.c (revision 21617c043cf2be06120e43f272b68c5ebd5f09fa)
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