48 ierr = CeedOperatorGetCeed(op, &ceed); PCeedChk(ierr);
52 ierr = CeedOperatorGetQFunction(op, &qf); PCeedChk(ierr);
53 CeedInt numinputfields, numoutputfields;
55 CeedVector assembledqf;
56 CeedElemRestriction rstr_q;
57 ierr = CeedOperatorLinearAssembleQFunction(
58 op, &assembledqf, &rstr_q, CEED_REQUEST_IMMEDIATE); PCeedChk(ierr);
61 ierr = CeedVectorGetLength(assembledqf, &qflength); PCeedChk(ierr);
63 CeedOperatorField *input_fields;
64 CeedOperatorField *output_fields;
65 ierr = CeedOperatorGetFields(op, &numinputfields, &input_fields,
66 &numoutputfields, &output_fields);
70 CeedQFunctionField *qffields;
71 ierr = CeedQFunctionGetFields(qf, &numinputfields, &qffields,
72 &numoutputfields, NULL);
74 CeedInt numemodein = 0, ncomp,
dim = 1;
75 CeedEvalMode *emodein = NULL;
76 CeedBasis basisin = NULL;
77 CeedElemRestriction rstrin = NULL;
78 for (CeedInt i=0; i<numinputfields; i++)
81 ierr = CeedOperatorFieldGetVector(input_fields[i], &vec); PCeedChk(ierr);
82 if (vec == CEED_VECTOR_ACTIVE)
85 ierr = CeedOperatorFieldGetBasis(input_fields[i], &basis); PCeedChk(ierr);
88 ierr = CeedBasisReferenceCopy(basis, &basisin); PCeedChk(ierr);
90#if CEED_VERSION_GE(0, 13, 0)
91 ierr = CeedBasisDestroy(&basis); PCeedChk(ierr);
93 ierr = CeedBasisGetNumComponents(basisin, &ncomp); PCeedChk(ierr);
94 ierr = CeedBasisGetDimension(basisin, &
dim); PCeedChk(ierr);
95 CeedElemRestriction rstr;
96 ierr = CeedOperatorFieldGetElemRestriction(input_fields[i], &rstr);
100 ierr = CeedElemRestrictionReferenceCopy(rstr, &rstrin); PCeedChk(ierr);
102#if CEED_VERSION_GE(0, 13, 0)
103 ierr = CeedElemRestrictionDestroy(&rstr); PCeedChk(ierr);
106 ierr = CeedQFunctionFieldGetEvalMode(qffields[i], &emode);
111 case CEED_EVAL_INTERP:
112 ierr = CeedHackRealloc(numemodein + 1, &emodein); PCeedChk(ierr);
113 emodein[numemodein] = emode;
117 ierr = CeedHackRealloc(numemodein +
dim, &emodein); PCeedChk(ierr);
118 for (CeedInt d=0; d<
dim; d++)
120 emodein[numemodein+d] = emode;
124 case CEED_EVAL_WEIGHT:
130#if CEED_VERSION_GE(0, 13, 0)
131 ierr = CeedVectorDestroy(&vec); PCeedChk(ierr);
136 ierr = CeedQFunctionGetFields(qf, &numinputfields, NULL, &numoutputfields,
137 &qffields); PCeedChk(ierr);
138 CeedInt numemodeout = 0;
139 CeedEvalMode *emodeout = NULL;
140 CeedBasis basisout = NULL;
141 CeedElemRestriction rstrout = NULL;
142 for (CeedInt i=0; i<numoutputfields; i++)
145 ierr = CeedOperatorFieldGetVector(output_fields[i], &vec); PCeedChk(ierr);
146 if (vec == CEED_VECTOR_ACTIVE)
149 ierr = CeedOperatorFieldGetBasis(output_fields[i], &basis); PCeedChk(ierr);
152 ierr = CeedBasisReferenceCopy(basis, &basisout); PCeedChk(ierr);
154#if CEED_VERSION_GE(0, 13, 0)
155 ierr = CeedBasisDestroy(&basis); PCeedChk(ierr);
157 CeedElemRestriction rstr;
158 ierr = CeedOperatorFieldGetElemRestriction(output_fields[i], &rstr);
162 ierr = CeedElemRestrictionReferenceCopy(rstr, &rstrout); PCeedChk(ierr);
164#if CEED_VERSION_GE(0, 13, 0)
165 ierr = CeedElemRestrictionDestroy(&rstr); PCeedChk(ierr);
168 ierr = CeedQFunctionFieldGetEvalMode(qffields[i], &emode);
173 case CEED_EVAL_INTERP:
174 ierr = CeedHackRealloc(numemodeout + 1, &emodeout); PCeedChk(ierr);
175 emodeout[numemodeout] = emode;
179 ierr = CeedHackRealloc(numemodeout +
dim, &emodeout); PCeedChk(ierr);
180 for (CeedInt d=0; d<
dim; d++)
182 emodeout[numemodeout+d] = emode;
186 case CEED_EVAL_WEIGHT:
192#if CEED_VERSION_GE(0, 13, 0)
193 ierr = CeedVectorDestroy(&vec); PCeedChk(ierr);
197 CeedInt nelem, elemsize, nqpts;
199 ierr = CeedElemRestrictionGetNumElements(rstrin, &nelem); PCeedChk(ierr);
200 ierr = CeedElemRestrictionGetElementSize(rstrin, &elemsize); PCeedChk(ierr);
201 ierr = CeedElemRestrictionGetLVectorSize(rstrin, &nnodes); PCeedChk(ierr);
202 ierr = CeedBasisGetNumQuadraturePoints(basisin, &nqpts); PCeedChk(ierr);
205 CeedVector index_vec;
206 ierr = CeedVectorCreate(ceed, nnodes, &index_vec); PCeedChk(ierr);
208 ierr = CeedVectorGetArrayWrite(index_vec, CEED_MEM_HOST, &array);
210 for (CeedSize i = 0; i < nnodes; ++i)
214 ierr = CeedVectorRestoreArray(index_vec, &array); PCeedChk(ierr);
216 ierr = CeedVectorCreate(ceed, nelem * elemsize, &elem_dof); PCeedChk(ierr);
217 ierr = CeedVectorSetValue(elem_dof, 0.0); PCeedChk(ierr);
218 CeedElemRestrictionApply(rstrin, CEED_NOTRANSPOSE, index_vec,
219 elem_dof, CEED_REQUEST_IMMEDIATE); PCeedChk(ierr);
220 const CeedScalar * elem_dof_a;
221 ierr = CeedVectorGetArrayRead(elem_dof, CEED_MEM_HOST, &elem_dof_a);
223 ierr = CeedVectorDestroy(&index_vec); PCeedChk(ierr);
227 MFEM_ASSERT(
out->Height() == nnodes,
"Sizes don't match!");
228 MFEM_ASSERT(
out->Width() == nnodes,
"Sizes don't match!");
229 const CeedScalar *interpin, *gradin;
230 ierr = CeedBasisGetInterp(basisin, &interpin); PCeedChk(ierr);
231 ierr = CeedBasisGetGrad(basisin, &gradin); PCeedChk(ierr);
233 const CeedScalar * assembledqfarray;
234 ierr = CeedVectorGetArrayRead(assembledqf, CEED_MEM_HOST, &assembledqfarray);
238#if CEED_VERSION_GE(0, 13, 0)
239 ierr = CeedElemRestrictionGetELayout(rstr_q, layout); PCeedChk(ierr);
241 ierr = CeedElemRestrictionGetELayout(rstr_q, &layout); PCeedChk(ierr);
243 ierr = CeedElemRestrictionDestroy(&rstr_q); PCeedChk(ierr);
246 const int skip_zeros = 0;
247 MFEM_ASSERT(numemodein == numemodeout,
248 "Ceed full assembly not implemented for this case.");
249 for (
int e = 0; e < nelem; ++e)
253 for (
int i = 0; i < elemsize; ++i)
255 rows[i] = elem_dof_a[e * elemsize + i];
266 for (
int q = 0; q < nqpts; ++q)
268 for (
int n = 0; n < elemsize; ++n)
271 for (
int ein = 0; ein < numemodein; ++ein)
273 if (emodein[ein] == CEED_EVAL_INTERP)
275 Bmat(numemodein * q + ein, n) += interpin[q * elemsize + n];
277 else if (emodein[ein] == CEED_EVAL_GRAD)
280 Bmat(numemodein * q + ein, n) += gradin[(din*nqpts+q) * elemsize + n];
284 MFEM_ASSERT(
false,
"Not implemented!");
288 for (
int ei = 0; ei < numemodein; ++ei)
290 for (
int ej = 0; ej < numemodein; ++ej)
292 const int comp = ei * numemodein + ej;
293 const int index = q*layout[0] + comp*layout[1] + e*layout[2];
294 Dmat(ei, ej, q) += assembledqfarray[
index];
301 for (
int j=0; j<elemsize; ++j)
303 for (
int q=0; q<nqpts; ++q)
305 int qq = numemodein*q;
306 for (
int ei = 0; ei < numemodein; ++ei)
308 for (
int ej = 0; ej < numemodein; ++ej)
310 BTD(j,qq+ei) += Bmat(qq+ej,j)*Dmat(ej,ei,q);
316 Mult(BTD, Bmat, elem_mat);
319 out->AddSubMatrix(rows, rows, elem_mat, skip_zeros);
322 ierr = CeedVectorRestoreArrayRead(elem_dof, &elem_dof_a); PCeedChk(ierr);
323 ierr = CeedVectorDestroy(&elem_dof); PCeedChk(ierr);
324 ierr = CeedVectorRestoreArrayRead(assembledqf, &assembledqfarray);
326 ierr = CeedVectorDestroy(&assembledqf); PCeedChk(ierr);
327 ierr = CeedElemRestrictionDestroy(&rstrin); PCeedChk(ierr);
328 ierr = CeedElemRestrictionDestroy(&rstrout); PCeedChk(ierr);
329 ierr = CeedBasisDestroy(&basisin); PCeedChk(ierr);
330 ierr = CeedBasisDestroy(&basisout); PCeedChk(ierr);