1d7b241e6Sjeremylt // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 2d7b241e6Sjeremylt // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 3d7b241e6Sjeremylt // reserved. See files LICENSE and NOTICE for details. 4d7b241e6Sjeremylt // 5d7b241e6Sjeremylt // This file is part of CEED, a collection of benchmarks, miniapps, software 6d7b241e6Sjeremylt // libraries and APIs for efficient high-order finite element and spectral 7d7b241e6Sjeremylt // element discretizations for exascale applications. For more information and 8d7b241e6Sjeremylt // source code availability see http://github.com/ceed. 9d7b241e6Sjeremylt // 10d7b241e6Sjeremylt // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 11d7b241e6Sjeremylt // a collaborative effort of two U.S. Department of Energy organizations (Office 12d7b241e6Sjeremylt // of Science and the National Nuclear Security Administration) responsible for 13d7b241e6Sjeremylt // the planning and preparation of a capable exascale ecosystem, including 14d7b241e6Sjeremylt // software, applications, hardware, advanced system engineering and early 15d7b241e6Sjeremylt // testbed platforms, in support of the nation's exascale computing imperative. 16d7b241e6Sjeremylt 17*3d576824SJeremy L Thompson #include <ceed.h> 18d863ab9bSjeremylt #include <ceed-backend.h> 19*3d576824SJeremy L Thompson #include <ceed-impl.h> 203bd813ffSjeremylt #include <math.h> 21*3d576824SJeremy L Thompson #include <stdbool.h> 22*3d576824SJeremy L Thompson #include <stdio.h> 23*3d576824SJeremy L Thompson #include <string.h> 24d7b241e6Sjeremylt 25dfdf5a53Sjeremylt /// @file 267a982d89SJeremy L. Thompson /// Implementation of CeedOperator interfaces 277a982d89SJeremy L. Thompson 287a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 297a982d89SJeremy L. Thompson /// CeedOperator Library Internal Functions 307a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 317a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorDeveloper 327a982d89SJeremy L. Thompson /// @{ 337a982d89SJeremy L. Thompson 347a982d89SJeremy L. Thompson /** 357a982d89SJeremy L. Thompson @brief Duplicate a CeedOperator with a reference Ceed to fallback for advanced 367a982d89SJeremy L. Thompson CeedOperator functionality 377a982d89SJeremy L. Thompson 387a982d89SJeremy L. Thompson @param op CeedOperator to create fallback for 397a982d89SJeremy L. Thompson 407a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 417a982d89SJeremy L. Thompson 427a982d89SJeremy L. Thompson @ref Developer 437a982d89SJeremy L. Thompson **/ 447a982d89SJeremy L. Thompson int CeedOperatorCreateFallback(CeedOperator op) { 457a982d89SJeremy L. Thompson int ierr; 467a982d89SJeremy L. Thompson 477a982d89SJeremy L. Thompson // Fallback Ceed 487a982d89SJeremy L. Thompson const char *resource, *fallbackresource; 497a982d89SJeremy L. Thompson ierr = CeedGetResource(op->ceed, &resource); CeedChk(ierr); 507a982d89SJeremy L. Thompson ierr = CeedGetOperatorFallbackResource(op->ceed, &fallbackresource); 517a982d89SJeremy L. Thompson CeedChk(ierr); 527a982d89SJeremy L. Thompson if (!strcmp(resource, fallbackresource)) 537a982d89SJeremy L. Thompson // LCOV_EXCL_START 547a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Backend %s cannot create an operator" 557a982d89SJeremy L. Thompson "fallback to resource %s", resource, fallbackresource); 567a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 577a982d89SJeremy L. Thompson 587a982d89SJeremy L. Thompson // Fallback Ceed 597a982d89SJeremy L. Thompson Ceed ceedref; 607a982d89SJeremy L. Thompson if (!op->ceed->opfallbackceed) { 617a982d89SJeremy L. Thompson ierr = CeedInit(fallbackresource, &ceedref); CeedChk(ierr); 627a982d89SJeremy L. Thompson ceedref->opfallbackparent = op->ceed; 63fc164cf7SWill Pazner ceedref->Error = op->ceed->Error; 647a982d89SJeremy L. Thompson op->ceed->opfallbackceed = ceedref; 657a982d89SJeremy L. Thompson } 667a982d89SJeremy L. Thompson ceedref = op->ceed->opfallbackceed; 677a982d89SJeremy L. Thompson 687a982d89SJeremy L. Thompson // Clone Op 697a982d89SJeremy L. Thompson CeedOperator opref; 707a982d89SJeremy L. Thompson ierr = CeedCalloc(1, &opref); CeedChk(ierr); 717a982d89SJeremy L. Thompson memcpy(opref, op, sizeof(*opref)); CeedChk(ierr); 727a982d89SJeremy L. Thompson opref->data = NULL; 737a982d89SJeremy L. Thompson opref->setupdone = 0; 747a982d89SJeremy L. Thompson opref->ceed = ceedref; 757a982d89SJeremy L. Thompson ierr = ceedref->OperatorCreate(opref); CeedChk(ierr); 767a982d89SJeremy L. Thompson op->opfallback = opref; 777a982d89SJeremy L. Thompson 787a982d89SJeremy L. Thompson // Clone QF 797a982d89SJeremy L. Thompson CeedQFunction qfref; 807a982d89SJeremy L. Thompson ierr = CeedCalloc(1, &qfref); CeedChk(ierr); 817a982d89SJeremy L. Thompson memcpy(qfref, (op->qf), sizeof(*qfref)); CeedChk(ierr); 827a982d89SJeremy L. Thompson qfref->data = NULL; 837a982d89SJeremy L. Thompson qfref->ceed = ceedref; 847a982d89SJeremy L. Thompson ierr = ceedref->QFunctionCreate(qfref); CeedChk(ierr); 857a982d89SJeremy L. Thompson opref->qf = qfref; 867a982d89SJeremy L. Thompson op->qffallback = qfref; 877a982d89SJeremy L. Thompson 887a982d89SJeremy L. Thompson return 0; 897a982d89SJeremy L. Thompson } 907a982d89SJeremy L. Thompson 917a982d89SJeremy L. Thompson /** 927a982d89SJeremy L. Thompson @brief Check if a CeedOperator is ready to be used. 937a982d89SJeremy L. Thompson 947a982d89SJeremy L. Thompson @param[in] ceed Ceed object for error handling 957a982d89SJeremy L. Thompson @param[in] op CeedOperator to check 967a982d89SJeremy L. Thompson 977a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 987a982d89SJeremy L. Thompson 997a982d89SJeremy L. Thompson @ref Developer 1007a982d89SJeremy L. Thompson **/ 1017a982d89SJeremy L. Thompson static int CeedOperatorCheckReady(Ceed ceed, CeedOperator op) { 1027a982d89SJeremy L. Thompson CeedQFunction qf = op->qf; 1037a982d89SJeremy L. Thompson 1047a982d89SJeremy L. Thompson if (op->composite) { 1057a982d89SJeremy L. Thompson if (!op->numsub) 1067a982d89SJeremy L. Thompson // LCOV_EXCL_START 1077a982d89SJeremy L. Thompson return CeedError(ceed, 1, "No suboperators set"); 1087a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 1097a982d89SJeremy L. Thompson } else { 1107a982d89SJeremy L. Thompson if (op->nfields == 0) 1117a982d89SJeremy L. Thompson // LCOV_EXCL_START 1127a982d89SJeremy L. Thompson return CeedError(ceed, 1, "No operator fields set"); 1137a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 1147a982d89SJeremy L. Thompson if (op->nfields < qf->numinputfields + qf->numoutputfields) 1157a982d89SJeremy L. Thompson // LCOV_EXCL_START 1167a982d89SJeremy L. Thompson return CeedError(ceed, 1, "Not all operator fields set"); 1177a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 1187a982d89SJeremy L. Thompson if (!op->hasrestriction) 1197a982d89SJeremy L. Thompson // LCOV_EXCL_START 1207a982d89SJeremy L. Thompson return CeedError(ceed, 1,"At least one restriction required"); 1217a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 1227a982d89SJeremy L. Thompson if (op->numqpoints == 0) 1237a982d89SJeremy L. Thompson // LCOV_EXCL_START 1247a982d89SJeremy L. Thompson return CeedError(ceed, 1,"At least one non-collocated basis required"); 1257a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 1267a982d89SJeremy L. Thompson } 1277a982d89SJeremy L. Thompson 1287a982d89SJeremy L. Thompson return 0; 1297a982d89SJeremy L. Thompson } 1307a982d89SJeremy L. Thompson 1317a982d89SJeremy L. Thompson /** 1327a982d89SJeremy L. Thompson @brief View a field of a CeedOperator 1337a982d89SJeremy L. Thompson 1347a982d89SJeremy L. Thompson @param[in] field Operator field to view 1354c4400c7SValeria Barra @param[in] qffield QFunction field (carries field name) 1367a982d89SJeremy L. Thompson @param[in] fieldnumber Number of field being viewed 1374c4400c7SValeria Barra @param[in] sub true indicates sub-operator, which increases indentation; false for top-level operator 1384c4400c7SValeria Barra @param[in] in true for an input field; false for output field 1397a982d89SJeremy L. Thompson @param[in] stream Stream to view to, e.g., stdout 1407a982d89SJeremy L. Thompson 1417a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1427a982d89SJeremy L. Thompson 1437a982d89SJeremy L. Thompson @ref Utility 1447a982d89SJeremy L. Thompson **/ 1457a982d89SJeremy L. Thompson static int CeedOperatorFieldView(CeedOperatorField field, 1467a982d89SJeremy L. Thompson CeedQFunctionField qffield, 1477a982d89SJeremy L. Thompson CeedInt fieldnumber, bool sub, bool in, 1487a982d89SJeremy L. Thompson FILE *stream) { 1497a982d89SJeremy L. Thompson const char *pre = sub ? " " : ""; 1507a982d89SJeremy L. Thompson const char *inout = in ? "Input" : "Output"; 1517a982d89SJeremy L. Thompson 1527a982d89SJeremy L. Thompson fprintf(stream, "%s %s Field [%d]:\n" 1537a982d89SJeremy L. Thompson "%s Name: \"%s\"\n", 1547a982d89SJeremy L. Thompson pre, inout, fieldnumber, pre, qffield->fieldname); 1557a982d89SJeremy L. Thompson 1567a982d89SJeremy L. Thompson if (field->basis == CEED_BASIS_COLLOCATED) 1577a982d89SJeremy L. Thompson fprintf(stream, "%s Collocated basis\n", pre); 1587a982d89SJeremy L. Thompson 1597a982d89SJeremy L. Thompson if (field->vec == CEED_VECTOR_ACTIVE) 1607a982d89SJeremy L. Thompson fprintf(stream, "%s Active vector\n", pre); 1617a982d89SJeremy L. Thompson else if (field->vec == CEED_VECTOR_NONE) 1627a982d89SJeremy L. Thompson fprintf(stream, "%s No vector\n", pre); 1637a982d89SJeremy L. Thompson 1647a982d89SJeremy L. Thompson return 0; 1657a982d89SJeremy L. Thompson } 1667a982d89SJeremy L. Thompson 1677a982d89SJeremy L. Thompson /** 1687a982d89SJeremy L. Thompson @brief View a single CeedOperator 1697a982d89SJeremy L. Thompson 1707a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 1717a982d89SJeremy L. Thompson @param[in] sub Boolean flag for sub-operator 1727a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 1737a982d89SJeremy L. Thompson 1747a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 1757a982d89SJeremy L. Thompson 1767a982d89SJeremy L. Thompson @ref Utility 1777a982d89SJeremy L. Thompson **/ 1787a982d89SJeremy L. Thompson int CeedOperatorSingleView(CeedOperator op, bool sub, FILE *stream) { 1797a982d89SJeremy L. Thompson int ierr; 1807a982d89SJeremy L. Thompson const char *pre = sub ? " " : ""; 1817a982d89SJeremy L. Thompson 1827a982d89SJeremy L. Thompson CeedInt totalfields; 1837a982d89SJeremy L. Thompson ierr = CeedOperatorGetNumArgs(op, &totalfields); CeedChk(ierr); 1847a982d89SJeremy L. Thompson 1857a982d89SJeremy L. Thompson fprintf(stream, "%s %d Field%s\n", pre, totalfields, totalfields>1 ? "s" : ""); 1867a982d89SJeremy L. Thompson 1877a982d89SJeremy L. Thompson fprintf(stream, "%s %d Input Field%s:\n", pre, op->qf->numinputfields, 1887a982d89SJeremy L. Thompson op->qf->numinputfields>1 ? "s" : ""); 1897a982d89SJeremy L. Thompson for (CeedInt i=0; i<op->qf->numinputfields; i++) { 1907a982d89SJeremy L. Thompson ierr = CeedOperatorFieldView(op->inputfields[i], op->qf->inputfields[i], 1917a982d89SJeremy L. Thompson i, sub, 1, stream); CeedChk(ierr); 1927a982d89SJeremy L. Thompson } 1937a982d89SJeremy L. Thompson 1947a982d89SJeremy L. Thompson fprintf(stream, "%s %d Output Field%s:\n", pre, op->qf->numoutputfields, 1957a982d89SJeremy L. Thompson op->qf->numoutputfields>1 ? "s" : ""); 1967a982d89SJeremy L. Thompson for (CeedInt i=0; i<op->qf->numoutputfields; i++) { 197829936eeSWill Pazner ierr = CeedOperatorFieldView(op->outputfields[i], op->qf->outputfields[i], 1987a982d89SJeremy L. Thompson i, sub, 0, stream); CeedChk(ierr); 1997a982d89SJeremy L. Thompson } 2007a982d89SJeremy L. Thompson 2017a982d89SJeremy L. Thompson return 0; 2027a982d89SJeremy L. Thompson } 2037a982d89SJeremy L. Thompson 204d99fa3c5SJeremy L Thompson /** 205d99fa3c5SJeremy L Thompson @brief Find the active vector basis for a CeedOperator 206d99fa3c5SJeremy L Thompson 207d99fa3c5SJeremy L Thompson @param[in] op CeedOperator to find active basis for 208d99fa3c5SJeremy L Thompson @param[out] activeBasis Basis for active input vector 209d99fa3c5SJeremy L Thompson 210d99fa3c5SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 211d99fa3c5SJeremy L Thompson 212d99fa3c5SJeremy L Thompson @ ref Developer 213d99fa3c5SJeremy L Thompson **/ 214d99fa3c5SJeremy L Thompson static int CeedOperatorGetActiveBasis(CeedOperator op, 215d99fa3c5SJeremy L Thompson CeedBasis *activeBasis) { 216d99fa3c5SJeremy L Thompson *activeBasis = NULL; 217d99fa3c5SJeremy L Thompson for (int i = 0; i < op->qf->numinputfields; i++) 218d99fa3c5SJeremy L Thompson if (op->inputfields[i]->vec == CEED_VECTOR_ACTIVE) { 219d99fa3c5SJeremy L Thompson *activeBasis = op->inputfields[i]->basis; 220d99fa3c5SJeremy L Thompson break; 221d99fa3c5SJeremy L Thompson } 222d99fa3c5SJeremy L Thompson 223d99fa3c5SJeremy L Thompson if (!*activeBasis) { 224d99fa3c5SJeremy L Thompson // LCOV_EXCL_START 225d99fa3c5SJeremy L Thompson int ierr; 226d99fa3c5SJeremy L Thompson Ceed ceed; 227d99fa3c5SJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 228d99fa3c5SJeremy L Thompson return CeedError(ceed, 1, 229d99fa3c5SJeremy L Thompson "No active basis found for automatic multigrid setup"); 230d99fa3c5SJeremy L Thompson // LCOV_EXCL_STOP 231d99fa3c5SJeremy L Thompson } 232d99fa3c5SJeremy L Thompson return 0; 233d99fa3c5SJeremy L Thompson } 234d99fa3c5SJeremy L Thompson 235d99fa3c5SJeremy L Thompson 236d99fa3c5SJeremy L Thompson /** 237d99fa3c5SJeremy L Thompson @brief Common code for creating a multigrid coarse operator and level 238d99fa3c5SJeremy L Thompson transfer operators for a CeedOperator 239d99fa3c5SJeremy L Thompson 240d99fa3c5SJeremy L Thompson @param[in] opFine Fine grid operator 241d99fa3c5SJeremy L Thompson @param[in] PMultFine L-vector multiplicity in parallel gather/scatter 242d99fa3c5SJeremy L Thompson @param[in] rstrCoarse Coarse grid restriction 243d99fa3c5SJeremy L Thompson @param[in] basisCoarse Coarse grid active vector basis 244d99fa3c5SJeremy L Thompson @param[in] basisCtoF Basis for coarse to fine interpolation 245d99fa3c5SJeremy L Thompson @param[out] opCoarse Coarse grid operator 246d99fa3c5SJeremy L Thompson @param[out] opProlong Coarse to fine operator 247d99fa3c5SJeremy L Thompson @param[out] opRestrict Fine to coarse operator 248d99fa3c5SJeremy L Thompson 249d99fa3c5SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 250d99fa3c5SJeremy L Thompson 251d99fa3c5SJeremy L Thompson @ref Developer 252d99fa3c5SJeremy L Thompson **/ 253d99fa3c5SJeremy L Thompson static int CeedOperatorMultigridLevel_Core(CeedOperator opFine, 254d99fa3c5SJeremy L Thompson CeedVector PMultFine, CeedElemRestriction rstrCoarse, CeedBasis basisCoarse, 255d99fa3c5SJeremy L Thompson CeedBasis basisCtoF, CeedOperator *opCoarse, CeedOperator *opProlong, 256d99fa3c5SJeremy L Thompson CeedOperator *opRestrict) { 257d99fa3c5SJeremy L Thompson int ierr; 258d99fa3c5SJeremy L Thompson Ceed ceed; 259d99fa3c5SJeremy L Thompson ierr = CeedOperatorGetCeed(opFine, &ceed); CeedChk(ierr); 260d99fa3c5SJeremy L Thompson 261d99fa3c5SJeremy L Thompson // Check for composite operator 262d99fa3c5SJeremy L Thompson bool isComposite; 263d99fa3c5SJeremy L Thompson ierr = CeedOperatorIsComposite(opFine, &isComposite); CeedChk(ierr); 264d99fa3c5SJeremy L Thompson if (isComposite) 265d99fa3c5SJeremy L Thompson // LCOV_EXCL_START 266d99fa3c5SJeremy L Thompson return CeedError(ceed, 1, 267d99fa3c5SJeremy L Thompson "Automatic multigrid setup for composite operators not supported"); 268d99fa3c5SJeremy L Thompson // LCOV_EXCL_STOP 269d99fa3c5SJeremy L Thompson 270d99fa3c5SJeremy L Thompson // Coarse Grid 271d99fa3c5SJeremy L Thompson ierr = CeedOperatorCreate(ceed, opFine->qf, opFine->dqf, opFine->dqfT, 272d99fa3c5SJeremy L Thompson opCoarse); CeedChk(ierr); 273d99fa3c5SJeremy L Thompson CeedElemRestriction rstrFine = NULL; 274d99fa3c5SJeremy L Thompson // -- Clone input fields 275d99fa3c5SJeremy L Thompson for (int i = 0; i < opFine->qf->numinputfields; i++) { 276d99fa3c5SJeremy L Thompson if (opFine->inputfields[i]->vec == CEED_VECTOR_ACTIVE) { 277d99fa3c5SJeremy L Thompson rstrFine = opFine->inputfields[i]->Erestrict; 278d99fa3c5SJeremy L Thompson ierr = CeedOperatorSetField(*opCoarse, opFine->inputfields[i]->fieldname, 279d99fa3c5SJeremy L Thompson rstrCoarse, basisCoarse, CEED_VECTOR_ACTIVE); 280d99fa3c5SJeremy L Thompson CeedChk(ierr); 281d99fa3c5SJeremy L Thompson } else { 282d99fa3c5SJeremy L Thompson ierr = CeedOperatorSetField(*opCoarse, opFine->inputfields[i]->fieldname, 283d99fa3c5SJeremy L Thompson opFine->inputfields[i]->Erestrict, 284d99fa3c5SJeremy L Thompson opFine->inputfields[i]->basis, 285d99fa3c5SJeremy L Thompson opFine->inputfields[i]->vec); CeedChk(ierr); 286d99fa3c5SJeremy L Thompson } 287d99fa3c5SJeremy L Thompson } 288d99fa3c5SJeremy L Thompson // -- Clone output fields 289d99fa3c5SJeremy L Thompson for (int i = 0; i < opFine->qf->numoutputfields; i++) { 290d99fa3c5SJeremy L Thompson if (opFine->outputfields[i]->vec == CEED_VECTOR_ACTIVE) { 291d99fa3c5SJeremy L Thompson ierr = CeedOperatorSetField(*opCoarse, opFine->outputfields[i]->fieldname, 292d99fa3c5SJeremy L Thompson rstrCoarse, basisCoarse, CEED_VECTOR_ACTIVE); 293d99fa3c5SJeremy L Thompson CeedChk(ierr); 294d99fa3c5SJeremy L Thompson } else { 295d99fa3c5SJeremy L Thompson ierr = CeedOperatorSetField(*opCoarse, opFine->outputfields[i]->fieldname, 296d99fa3c5SJeremy L Thompson opFine->outputfields[i]->Erestrict, 297d99fa3c5SJeremy L Thompson opFine->outputfields[i]->basis, 298d99fa3c5SJeremy L Thompson opFine->outputfields[i]->vec); CeedChk(ierr); 299d99fa3c5SJeremy L Thompson } 300d99fa3c5SJeremy L Thompson } 301d99fa3c5SJeremy L Thompson 302d99fa3c5SJeremy L Thompson // Multiplicity vector 303d99fa3c5SJeremy L Thompson CeedVector multVec, multE; 304d99fa3c5SJeremy L Thompson ierr = CeedElemRestrictionCreateVector(rstrFine, &multVec, &multE); 305d99fa3c5SJeremy L Thompson CeedChk(ierr); 306d99fa3c5SJeremy L Thompson ierr = CeedVectorSetValue(multE, 0.0); CeedChk(ierr); 307d99fa3c5SJeremy L Thompson ierr = CeedElemRestrictionApply(rstrFine, CEED_NOTRANSPOSE, PMultFine, multE, 308d99fa3c5SJeremy L Thompson CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 309d99fa3c5SJeremy L Thompson ierr = CeedVectorSetValue(multVec, 0.0); CeedChk(ierr); 310d99fa3c5SJeremy L Thompson ierr = CeedElemRestrictionApply(rstrFine, CEED_TRANSPOSE, multE, multVec, 311d99fa3c5SJeremy L Thompson CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 312d99fa3c5SJeremy L Thompson ierr = CeedVectorDestroy(&multE); CeedChk(ierr); 313d99fa3c5SJeremy L Thompson ierr = CeedVectorReciprocal(multVec); CeedChk(ierr); 314d99fa3c5SJeremy L Thompson 315d99fa3c5SJeremy L Thompson // Restriction 316d99fa3c5SJeremy L Thompson CeedInt ncomp; 317d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumComponents(basisCoarse, &ncomp); CeedChk(ierr); 318d99fa3c5SJeremy L Thompson CeedQFunction qfRestrict; 319d99fa3c5SJeremy L Thompson ierr = CeedQFunctionCreateInteriorByName(ceed, "Scale", &qfRestrict); 320d99fa3c5SJeremy L Thompson CeedChk(ierr); 321777ff853SJeremy L Thompson CeedInt *ncompRData; 322777ff853SJeremy L Thompson ierr = CeedCalloc(1, &ncompRData); CeedChk(ierr); 323777ff853SJeremy L Thompson ncompRData[0] = ncomp; 324777ff853SJeremy L Thompson CeedQFunctionContext ctxR; 325777ff853SJeremy L Thompson ierr = CeedQFunctionContextCreate(ceed, &ctxR); CeedChk(ierr); 326777ff853SJeremy L Thompson ierr = CeedQFunctionContextSetData(ctxR, CEED_MEM_HOST, CEED_OWN_POINTER, 327777ff853SJeremy L Thompson sizeof(*ncompRData), ncompRData); 328777ff853SJeremy L Thompson CeedChk(ierr); 329777ff853SJeremy L Thompson ierr = CeedQFunctionSetContext(qfRestrict, ctxR); CeedChk(ierr); 330777ff853SJeremy L Thompson ierr = CeedQFunctionContextDestroy(&ctxR); CeedChk(ierr); 331d99fa3c5SJeremy L Thompson ierr = CeedQFunctionAddInput(qfRestrict, "input", ncomp, CEED_EVAL_NONE); 332d99fa3c5SJeremy L Thompson CeedChk(ierr); 333d99fa3c5SJeremy L Thompson ierr = CeedQFunctionAddInput(qfRestrict, "scale", ncomp, CEED_EVAL_NONE); 334d99fa3c5SJeremy L Thompson CeedChk(ierr); 335d99fa3c5SJeremy L Thompson ierr = CeedQFunctionAddOutput(qfRestrict, "output", ncomp, CEED_EVAL_INTERP); 336d99fa3c5SJeremy L Thompson CeedChk(ierr); 337d99fa3c5SJeremy L Thompson 338d99fa3c5SJeremy L Thompson ierr = CeedOperatorCreate(ceed, qfRestrict, CEED_QFUNCTION_NONE, 339d99fa3c5SJeremy L Thompson CEED_QFUNCTION_NONE, opRestrict); 340d99fa3c5SJeremy L Thompson CeedChk(ierr); 341d99fa3c5SJeremy L Thompson ierr = CeedOperatorSetField(*opRestrict, "input", rstrFine, 342d99fa3c5SJeremy L Thompson CEED_BASIS_COLLOCATED, CEED_VECTOR_ACTIVE); 343d99fa3c5SJeremy L Thompson CeedChk(ierr); 344d99fa3c5SJeremy L Thompson ierr = CeedOperatorSetField(*opRestrict, "scale", rstrFine, 345d99fa3c5SJeremy L Thompson CEED_BASIS_COLLOCATED, multVec); 346d99fa3c5SJeremy L Thompson CeedChk(ierr); 347d99fa3c5SJeremy L Thompson ierr = CeedOperatorSetField(*opRestrict, "output", rstrCoarse, basisCtoF, 348d99fa3c5SJeremy L Thompson CEED_VECTOR_ACTIVE); CeedChk(ierr); 349d99fa3c5SJeremy L Thompson 350d99fa3c5SJeremy L Thompson // Prolongation 351d99fa3c5SJeremy L Thompson CeedQFunction qfProlong; 352d99fa3c5SJeremy L Thompson ierr = CeedQFunctionCreateInteriorByName(ceed, "Scale", &qfProlong); 353d99fa3c5SJeremy L Thompson CeedChk(ierr); 354777ff853SJeremy L Thompson CeedInt *ncompPData; 355777ff853SJeremy L Thompson ierr = CeedCalloc(1, &ncompPData); CeedChk(ierr); 356777ff853SJeremy L Thompson ncompPData[0] = ncomp; 357777ff853SJeremy L Thompson CeedQFunctionContext ctxP; 358777ff853SJeremy L Thompson ierr = CeedQFunctionContextCreate(ceed, &ctxP); CeedChk(ierr); 359777ff853SJeremy L Thompson ierr = CeedQFunctionContextSetData(ctxP, CEED_MEM_HOST, CEED_OWN_POINTER, 360777ff853SJeremy L Thompson sizeof(*ncompPData), ncompPData); 361777ff853SJeremy L Thompson CeedChk(ierr); 362777ff853SJeremy L Thompson ierr = CeedQFunctionSetContext(qfProlong, ctxP); CeedChk(ierr); 363777ff853SJeremy L Thompson ierr = CeedQFunctionContextDestroy(&ctxP); CeedChk(ierr); 364d99fa3c5SJeremy L Thompson ierr = CeedQFunctionAddInput(qfProlong, "input", ncomp, CEED_EVAL_INTERP); 365d99fa3c5SJeremy L Thompson CeedChk(ierr); 366d99fa3c5SJeremy L Thompson ierr = CeedQFunctionAddInput(qfProlong, "scale", ncomp, CEED_EVAL_NONE); 367d99fa3c5SJeremy L Thompson CeedChk(ierr); 368d99fa3c5SJeremy L Thompson ierr = CeedQFunctionAddOutput(qfProlong, "output", ncomp, CEED_EVAL_NONE); 369d99fa3c5SJeremy L Thompson CeedChk(ierr); 370d99fa3c5SJeremy L Thompson 371d99fa3c5SJeremy L Thompson ierr = CeedOperatorCreate(ceed, qfProlong, CEED_QFUNCTION_NONE, 372d99fa3c5SJeremy L Thompson CEED_QFUNCTION_NONE, opProlong); 373d99fa3c5SJeremy L Thompson CeedChk(ierr); 374d99fa3c5SJeremy L Thompson ierr = CeedOperatorSetField(*opProlong, "input", rstrCoarse, basisCtoF, 375d99fa3c5SJeremy L Thompson CEED_VECTOR_ACTIVE); CeedChk(ierr); 376d99fa3c5SJeremy L Thompson ierr = CeedOperatorSetField(*opProlong, "scale", rstrFine, 377d99fa3c5SJeremy L Thompson CEED_BASIS_COLLOCATED, multVec); 378d99fa3c5SJeremy L Thompson CeedChk(ierr); 379d99fa3c5SJeremy L Thompson ierr = CeedOperatorSetField(*opProlong, "output", rstrFine, 380d99fa3c5SJeremy L Thompson CEED_BASIS_COLLOCATED, CEED_VECTOR_ACTIVE); 381d99fa3c5SJeremy L Thompson CeedChk(ierr); 382d99fa3c5SJeremy L Thompson 383d99fa3c5SJeremy L Thompson // Cleanup 384d99fa3c5SJeremy L Thompson ierr = CeedVectorDestroy(&multVec); CeedChk(ierr); 385d99fa3c5SJeremy L Thompson ierr = CeedBasisDestroy(&basisCtoF); CeedChk(ierr); 386d99fa3c5SJeremy L Thompson ierr = CeedQFunctionDestroy(&qfRestrict); CeedChk(ierr); 387d99fa3c5SJeremy L Thompson ierr = CeedQFunctionDestroy(&qfProlong); CeedChk(ierr); 388d99fa3c5SJeremy L Thompson 389d99fa3c5SJeremy L Thompson return 0; 390d99fa3c5SJeremy L Thompson } 391d99fa3c5SJeremy L Thompson 3927a982d89SJeremy L. Thompson /// @} 3937a982d89SJeremy L. Thompson 3947a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3957a982d89SJeremy L. Thompson /// CeedOperator Backend API 3967a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3977a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorBackend 3987a982d89SJeremy L. Thompson /// @{ 3997a982d89SJeremy L. Thompson 4007a982d89SJeremy L. Thompson /** 4017a982d89SJeremy L. Thompson @brief Get the Ceed associated with a CeedOperator 4027a982d89SJeremy L. Thompson 4037a982d89SJeremy L. Thompson @param op CeedOperator 4047a982d89SJeremy L. Thompson @param[out] ceed Variable to store Ceed 4057a982d89SJeremy L. Thompson 4067a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4077a982d89SJeremy L. Thompson 4087a982d89SJeremy L. Thompson @ref Backend 4097a982d89SJeremy L. Thompson **/ 4107a982d89SJeremy L. Thompson 4117a982d89SJeremy L. Thompson int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 4127a982d89SJeremy L. Thompson *ceed = op->ceed; 4137a982d89SJeremy L. Thompson return 0; 4147a982d89SJeremy L. Thompson } 4157a982d89SJeremy L. Thompson 4167a982d89SJeremy L. Thompson /** 4177a982d89SJeremy L. Thompson @brief Get the number of elements associated with a CeedOperator 4187a982d89SJeremy L. Thompson 4197a982d89SJeremy L. Thompson @param op CeedOperator 4207a982d89SJeremy L. Thompson @param[out] numelem Variable to store number of elements 4217a982d89SJeremy L. Thompson 4227a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4237a982d89SJeremy L. Thompson 4247a982d89SJeremy L. Thompson @ref Backend 4257a982d89SJeremy L. Thompson **/ 4267a982d89SJeremy L. Thompson 4277a982d89SJeremy L. Thompson int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) { 4287a982d89SJeremy L. Thompson if (op->composite) 4297a982d89SJeremy L. Thompson // LCOV_EXCL_START 4307a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 4317a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4327a982d89SJeremy L. Thompson 4337a982d89SJeremy L. Thompson *numelem = op->numelements; 4347a982d89SJeremy L. Thompson return 0; 4357a982d89SJeremy L. Thompson } 4367a982d89SJeremy L. Thompson 4377a982d89SJeremy L. Thompson /** 4387a982d89SJeremy L. Thompson @brief Get the number of quadrature points associated with a CeedOperator 4397a982d89SJeremy L. Thompson 4407a982d89SJeremy L. Thompson @param op CeedOperator 4417a982d89SJeremy L. Thompson @param[out] numqpts Variable to store vector number of quadrature points 4427a982d89SJeremy L. Thompson 4437a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4447a982d89SJeremy L. Thompson 4457a982d89SJeremy L. Thompson @ref Backend 4467a982d89SJeremy L. Thompson **/ 4477a982d89SJeremy L. Thompson 4487a982d89SJeremy L. Thompson int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) { 4497a982d89SJeremy L. Thompson if (op->composite) 4507a982d89SJeremy L. Thompson // LCOV_EXCL_START 4517a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 4527a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4537a982d89SJeremy L. Thompson 4547a982d89SJeremy L. Thompson *numqpts = op->numqpoints; 4557a982d89SJeremy L. Thompson return 0; 4567a982d89SJeremy L. Thompson } 4577a982d89SJeremy L. Thompson 4587a982d89SJeremy L. Thompson /** 4597a982d89SJeremy L. Thompson @brief Get the number of arguments associated with a CeedOperator 4607a982d89SJeremy L. Thompson 4617a982d89SJeremy L. Thompson @param op CeedOperator 4627a982d89SJeremy L. Thompson @param[out] numargs Variable to store vector number of arguments 4637a982d89SJeremy L. Thompson 4647a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4657a982d89SJeremy L. Thompson 4667a982d89SJeremy L. Thompson @ref Backend 4677a982d89SJeremy L. Thompson **/ 4687a982d89SJeremy L. Thompson 4697a982d89SJeremy L. Thompson int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) { 4707a982d89SJeremy L. Thompson if (op->composite) 4717a982d89SJeremy L. Thompson // LCOV_EXCL_START 4727a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Not defined for composite operators"); 4737a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4747a982d89SJeremy L. Thompson 4757a982d89SJeremy L. Thompson *numargs = op->nfields; 4767a982d89SJeremy L. Thompson return 0; 4777a982d89SJeremy L. Thompson } 4787a982d89SJeremy L. Thompson 4797a982d89SJeremy L. Thompson /** 4807a982d89SJeremy L. Thompson @brief Get the setup status of a CeedOperator 4817a982d89SJeremy L. Thompson 4827a982d89SJeremy L. Thompson @param op CeedOperator 483fd364f38SJeremy L Thompson @param[out] issetupdone Variable to store setup status 4847a982d89SJeremy L. Thompson 4857a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4867a982d89SJeremy L. Thompson 4877a982d89SJeremy L. Thompson @ref Backend 4887a982d89SJeremy L. Thompson **/ 4897a982d89SJeremy L. Thompson 490fd364f38SJeremy L Thompson int CeedOperatorIsSetupDone(CeedOperator op, bool *issetupdone) { 491fd364f38SJeremy L Thompson *issetupdone = op->setupdone; 4927a982d89SJeremy L. Thompson return 0; 4937a982d89SJeremy L. Thompson } 4947a982d89SJeremy L. Thompson 4957a982d89SJeremy L. Thompson /** 4967a982d89SJeremy L. Thompson @brief Get the QFunction associated with a CeedOperator 4977a982d89SJeremy L. Thompson 4987a982d89SJeremy L. Thompson @param op CeedOperator 4997a982d89SJeremy L. Thompson @param[out] qf Variable to store QFunction 5007a982d89SJeremy L. Thompson 5017a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5027a982d89SJeremy L. Thompson 5037a982d89SJeremy L. Thompson @ref Backend 5047a982d89SJeremy L. Thompson **/ 5057a982d89SJeremy L. Thompson 5067a982d89SJeremy L. Thompson int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 5077a982d89SJeremy L. Thompson if (op->composite) 5087a982d89SJeremy L. Thompson // LCOV_EXCL_START 5097a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 5107a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 5117a982d89SJeremy L. Thompson 5127a982d89SJeremy L. Thompson *qf = op->qf; 5137a982d89SJeremy L. Thompson return 0; 5147a982d89SJeremy L. Thompson } 5157a982d89SJeremy L. Thompson 5167a982d89SJeremy L. Thompson /** 517c04a41a7SJeremy L Thompson @brief Get a boolean value indicating if the CeedOperator is composite 518c04a41a7SJeremy L Thompson 519c04a41a7SJeremy L Thompson @param op CeedOperator 520fd364f38SJeremy L Thompson @param[out] iscomposite Variable to store composite status 521c04a41a7SJeremy L Thompson 522c04a41a7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 523c04a41a7SJeremy L Thompson 524c04a41a7SJeremy L Thompson @ref Backend 525c04a41a7SJeremy L Thompson **/ 526c04a41a7SJeremy L Thompson 527fd364f38SJeremy L Thompson int CeedOperatorIsComposite(CeedOperator op, bool *iscomposite) { 528fd364f38SJeremy L Thompson *iscomposite = op->composite; 529c04a41a7SJeremy L Thompson return 0; 530c04a41a7SJeremy L Thompson } 531c04a41a7SJeremy L Thompson 532c04a41a7SJeremy L Thompson /** 5337a982d89SJeremy L. Thompson @brief Get the number of suboperators associated with a CeedOperator 5347a982d89SJeremy L. Thompson 5357a982d89SJeremy L. Thompson @param op CeedOperator 5367a982d89SJeremy L. Thompson @param[out] numsub Variable to store number of suboperators 5377a982d89SJeremy L. Thompson 5387a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5397a982d89SJeremy L. Thompson 5407a982d89SJeremy L. Thompson @ref Backend 5417a982d89SJeremy L. Thompson **/ 5427a982d89SJeremy L. Thompson 5437a982d89SJeremy L. Thompson int CeedOperatorGetNumSub(CeedOperator op, CeedInt *numsub) { 5447a982d89SJeremy L. Thompson if (!op->composite) 5457a982d89SJeremy L. Thompson // LCOV_EXCL_START 5467a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 5477a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 5487a982d89SJeremy L. Thompson 5497a982d89SJeremy L. Thompson *numsub = op->numsub; 5507a982d89SJeremy L. Thompson return 0; 5517a982d89SJeremy L. Thompson } 5527a982d89SJeremy L. Thompson 5537a982d89SJeremy L. Thompson /** 5547a982d89SJeremy L. Thompson @brief Get the list of suboperators associated with a CeedOperator 5557a982d89SJeremy L. Thompson 5567a982d89SJeremy L. Thompson @param op CeedOperator 5577a982d89SJeremy L. Thompson @param[out] suboperators Variable to store list of suboperators 5587a982d89SJeremy L. Thompson 5597a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5607a982d89SJeremy L. Thompson 5617a982d89SJeremy L. Thompson @ref Backend 5627a982d89SJeremy L. Thompson **/ 5637a982d89SJeremy L. Thompson 5647a982d89SJeremy L. Thompson int CeedOperatorGetSubList(CeedOperator op, CeedOperator **suboperators) { 5657a982d89SJeremy L. Thompson if (!op->composite) 5667a982d89SJeremy L. Thompson // LCOV_EXCL_START 5677a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 5687a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 5697a982d89SJeremy L. Thompson 5707a982d89SJeremy L. Thompson *suboperators = op->suboperators; 5717a982d89SJeremy L. Thompson return 0; 5727a982d89SJeremy L. Thompson } 5737a982d89SJeremy L. Thompson 5747a982d89SJeremy L. Thompson /** 5757a982d89SJeremy L. Thompson @brief Get the backend data of a CeedOperator 5767a982d89SJeremy L. Thompson 5777a982d89SJeremy L. Thompson @param op CeedOperator 5787a982d89SJeremy L. Thompson @param[out] data Variable to store data 5797a982d89SJeremy L. Thompson 5807a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5817a982d89SJeremy L. Thompson 5827a982d89SJeremy L. Thompson @ref Backend 5837a982d89SJeremy L. Thompson **/ 5847a982d89SJeremy L. Thompson 585777ff853SJeremy L Thompson int CeedOperatorGetData(CeedOperator op, void *data) { 586777ff853SJeremy L Thompson *(void **)data = op->data; 5877a982d89SJeremy L. Thompson return 0; 5887a982d89SJeremy L. Thompson } 5897a982d89SJeremy L. Thompson 5907a982d89SJeremy L. Thompson /** 5917a982d89SJeremy L. Thompson @brief Set the backend data of a CeedOperator 5927a982d89SJeremy L. Thompson 5937a982d89SJeremy L. Thompson @param[out] op CeedOperator 5947a982d89SJeremy L. Thompson @param data Data to set 5957a982d89SJeremy L. Thompson 5967a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5977a982d89SJeremy L. Thompson 5987a982d89SJeremy L. Thompson @ref Backend 5997a982d89SJeremy L. Thompson **/ 6007a982d89SJeremy L. Thompson 601777ff853SJeremy L Thompson int CeedOperatorSetData(CeedOperator op, void *data) { 602777ff853SJeremy L Thompson op->data = data; 6037a982d89SJeremy L. Thompson return 0; 6047a982d89SJeremy L. Thompson } 6057a982d89SJeremy L. Thompson 6067a982d89SJeremy L. Thompson /** 6077a982d89SJeremy L. Thompson @brief Set the setup flag of a CeedOperator to True 6087a982d89SJeremy L. Thompson 6097a982d89SJeremy L. Thompson @param op CeedOperator 6107a982d89SJeremy L. Thompson 6117a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6127a982d89SJeremy L. Thompson 6137a982d89SJeremy L. Thompson @ref Backend 6147a982d89SJeremy L. Thompson **/ 6157a982d89SJeremy L. Thompson 6167a982d89SJeremy L. Thompson int CeedOperatorSetSetupDone(CeedOperator op) { 6177a982d89SJeremy L. Thompson op->setupdone = 1; 6187a982d89SJeremy L. Thompson return 0; 6197a982d89SJeremy L. Thompson } 6207a982d89SJeremy L. Thompson 6217a982d89SJeremy L. Thompson /** 6227a982d89SJeremy L. Thompson @brief Get the CeedOperatorFields of a CeedOperator 6237a982d89SJeremy L. Thompson 6247a982d89SJeremy L. Thompson @param op CeedOperator 6257a982d89SJeremy L. Thompson @param[out] inputfields Variable to store inputfields 6267a982d89SJeremy L. Thompson @param[out] outputfields Variable to store outputfields 6277a982d89SJeremy L. Thompson 6287a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6297a982d89SJeremy L. Thompson 6307a982d89SJeremy L. Thompson @ref Backend 6317a982d89SJeremy L. Thompson **/ 6327a982d89SJeremy L. Thompson 6337a982d89SJeremy L. Thompson int CeedOperatorGetFields(CeedOperator op, CeedOperatorField **inputfields, 6347a982d89SJeremy L. Thompson CeedOperatorField **outputfields) { 6357a982d89SJeremy L. Thompson if (op->composite) 6367a982d89SJeremy L. Thompson // LCOV_EXCL_START 6377a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 6387a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 6397a982d89SJeremy L. Thompson 6407a982d89SJeremy L. Thompson if (inputfields) *inputfields = op->inputfields; 6417a982d89SJeremy L. Thompson if (outputfields) *outputfields = op->outputfields; 6427a982d89SJeremy L. Thompson return 0; 6437a982d89SJeremy L. Thompson } 6447a982d89SJeremy L. Thompson 6457a982d89SJeremy L. Thompson /** 6467a982d89SJeremy L. Thompson @brief Get the CeedElemRestriction of a CeedOperatorField 6477a982d89SJeremy L. Thompson 6487a982d89SJeremy L. Thompson @param opfield CeedOperatorField 6497a982d89SJeremy L. Thompson @param[out] rstr Variable to store CeedElemRestriction 6507a982d89SJeremy L. Thompson 6517a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6527a982d89SJeremy L. Thompson 6537a982d89SJeremy L. Thompson @ref Backend 6547a982d89SJeremy L. Thompson **/ 6557a982d89SJeremy L. Thompson 6567a982d89SJeremy L. Thompson int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield, 6577a982d89SJeremy L. Thompson CeedElemRestriction *rstr) { 6587a982d89SJeremy L. Thompson *rstr = opfield->Erestrict; 6597a982d89SJeremy L. Thompson return 0; 6607a982d89SJeremy L. Thompson } 6617a982d89SJeremy L. Thompson 6627a982d89SJeremy L. Thompson /** 6637a982d89SJeremy L. Thompson @brief Get the CeedBasis of a CeedOperatorField 6647a982d89SJeremy L. Thompson 6657a982d89SJeremy L. Thompson @param opfield CeedOperatorField 6667a982d89SJeremy L. Thompson @param[out] basis Variable to store CeedBasis 6677a982d89SJeremy L. Thompson 6687a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6697a982d89SJeremy L. Thompson 6707a982d89SJeremy L. Thompson @ref Backend 6717a982d89SJeremy L. Thompson **/ 6727a982d89SJeremy L. Thompson 6737a982d89SJeremy L. Thompson int CeedOperatorFieldGetBasis(CeedOperatorField opfield, CeedBasis *basis) { 6747a982d89SJeremy L. Thompson *basis = opfield->basis; 6757a982d89SJeremy L. Thompson return 0; 6767a982d89SJeremy L. Thompson } 6777a982d89SJeremy L. Thompson 6787a982d89SJeremy L. Thompson /** 6797a982d89SJeremy L. Thompson @brief Get the CeedVector of a CeedOperatorField 6807a982d89SJeremy L. Thompson 6817a982d89SJeremy L. Thompson @param opfield CeedOperatorField 6827a982d89SJeremy L. Thompson @param[out] vec Variable to store CeedVector 6837a982d89SJeremy L. Thompson 6847a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6857a982d89SJeremy L. Thompson 6867a982d89SJeremy L. Thompson @ref Backend 6877a982d89SJeremy L. Thompson **/ 6887a982d89SJeremy L. Thompson 6897a982d89SJeremy L. Thompson int CeedOperatorFieldGetVector(CeedOperatorField opfield, CeedVector *vec) { 6907a982d89SJeremy L. Thompson *vec = opfield->vec; 6917a982d89SJeremy L. Thompson return 0; 6927a982d89SJeremy L. Thompson } 6937a982d89SJeremy L. Thompson 6947a982d89SJeremy L. Thompson /// @} 6957a982d89SJeremy L. Thompson 6967a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 6977a982d89SJeremy L. Thompson /// CeedOperator Public API 6987a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 6997a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorUser 700dfdf5a53Sjeremylt /// @{ 701d7b241e6Sjeremylt 702d7b241e6Sjeremylt /** 7030219ea01SJeremy L Thompson @brief Create a CeedOperator and associate a CeedQFunction. A CeedBasis and 7040219ea01SJeremy L Thompson CeedElemRestriction can be associated with CeedQFunction fields with 7050219ea01SJeremy L Thompson \ref CeedOperatorSetField. 706d7b241e6Sjeremylt 707b11c1e72Sjeremylt @param ceed A Ceed object where the CeedOperator will be created 708d7b241e6Sjeremylt @param qf QFunction defining the action of the operator at quadrature points 70934138859Sjeremylt @param dqf QFunction defining the action of the Jacobian of @a qf (or 7104cc79fe7SJed Brown @ref CEED_QFUNCTION_NONE) 711d7b241e6Sjeremylt @param dqfT QFunction defining the action of the transpose of the Jacobian 7124cc79fe7SJed Brown of @a qf (or @ref CEED_QFUNCTION_NONE) 713b11c1e72Sjeremylt @param[out] op Address of the variable where the newly created 714b11c1e72Sjeremylt CeedOperator will be stored 715b11c1e72Sjeremylt 716b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 717dfdf5a53Sjeremylt 7187a982d89SJeremy L. Thompson @ref User 719d7b241e6Sjeremylt */ 720d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, 721d7b241e6Sjeremylt CeedQFunction dqfT, CeedOperator *op) { 722d7b241e6Sjeremylt int ierr; 723d7b241e6Sjeremylt 7245fe0d4faSjeremylt if (!ceed->OperatorCreate) { 7255fe0d4faSjeremylt Ceed delegate; 726aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 7275fe0d4faSjeremylt 7285fe0d4faSjeremylt if (!delegate) 729c042f62fSJeremy L Thompson // LCOV_EXCL_START 7305fe0d4faSjeremylt return CeedError(ceed, 1, "Backend does not support OperatorCreate"); 731c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 7325fe0d4faSjeremylt 7335fe0d4faSjeremylt ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr); 7345fe0d4faSjeremylt return 0; 7355fe0d4faSjeremylt } 7365fe0d4faSjeremylt 737b3b7035fSJeremy L Thompson if (!qf || qf == CEED_QFUNCTION_NONE) 738b3b7035fSJeremy L Thompson // LCOV_EXCL_START 739b3b7035fSJeremy L Thompson return CeedError(ceed, 1, "Operator must have a valid QFunction."); 740b3b7035fSJeremy L Thompson // LCOV_EXCL_STOP 741d7b241e6Sjeremylt ierr = CeedCalloc(1, op); CeedChk(ierr); 742d7b241e6Sjeremylt (*op)->ceed = ceed; 743d7b241e6Sjeremylt ceed->refcount++; 744d7b241e6Sjeremylt (*op)->refcount = 1; 745d7b241e6Sjeremylt (*op)->qf = qf; 746d7b241e6Sjeremylt qf->refcount++; 747442e7f0bSjeremylt if (dqf && dqf != CEED_QFUNCTION_NONE) { 748d7b241e6Sjeremylt (*op)->dqf = dqf; 749442e7f0bSjeremylt dqf->refcount++; 750442e7f0bSjeremylt } 751442e7f0bSjeremylt if (dqfT && dqfT != CEED_QFUNCTION_NONE) { 752d7b241e6Sjeremylt (*op)->dqfT = dqfT; 753442e7f0bSjeremylt dqfT->refcount++; 754442e7f0bSjeremylt } 755fe2413ffSjeremylt ierr = CeedCalloc(16, &(*op)->inputfields); CeedChk(ierr); 756fe2413ffSjeremylt ierr = CeedCalloc(16, &(*op)->outputfields); CeedChk(ierr); 757d7b241e6Sjeremylt ierr = ceed->OperatorCreate(*op); CeedChk(ierr); 758d7b241e6Sjeremylt return 0; 759d7b241e6Sjeremylt } 760d7b241e6Sjeremylt 761d7b241e6Sjeremylt /** 76252d6035fSJeremy L Thompson @brief Create an operator that composes the action of several operators 76352d6035fSJeremy L Thompson 76452d6035fSJeremy L Thompson @param ceed A Ceed object where the CeedOperator will be created 76552d6035fSJeremy L Thompson @param[out] op Address of the variable where the newly created 76652d6035fSJeremy L Thompson Composite CeedOperator will be stored 76752d6035fSJeremy L Thompson 76852d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 76952d6035fSJeremy L Thompson 7707a982d89SJeremy L. Thompson @ref User 77152d6035fSJeremy L Thompson */ 77252d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) { 77352d6035fSJeremy L Thompson int ierr; 77452d6035fSJeremy L Thompson 77552d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 77652d6035fSJeremy L Thompson Ceed delegate; 777aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 77852d6035fSJeremy L Thompson 779250756a7Sjeremylt if (delegate) { 78052d6035fSJeremy L Thompson ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr); 78152d6035fSJeremy L Thompson return 0; 78252d6035fSJeremy L Thompson } 783250756a7Sjeremylt } 78452d6035fSJeremy L Thompson 78552d6035fSJeremy L Thompson ierr = CeedCalloc(1, op); CeedChk(ierr); 78652d6035fSJeremy L Thompson (*op)->ceed = ceed; 78752d6035fSJeremy L Thompson ceed->refcount++; 78852d6035fSJeremy L Thompson (*op)->composite = true; 78952d6035fSJeremy L Thompson ierr = CeedCalloc(16, &(*op)->suboperators); CeedChk(ierr); 790250756a7Sjeremylt 791250756a7Sjeremylt if (ceed->CompositeOperatorCreate) { 79252d6035fSJeremy L Thompson ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr); 793250756a7Sjeremylt } 79452d6035fSJeremy L Thompson return 0; 79552d6035fSJeremy L Thompson } 79652d6035fSJeremy L Thompson 79752d6035fSJeremy L Thompson /** 798b11c1e72Sjeremylt @brief Provide a field to a CeedOperator for use by its CeedQFunction 799d7b241e6Sjeremylt 800d7b241e6Sjeremylt This function is used to specify both active and passive fields to a 801d7b241e6Sjeremylt CeedOperator. For passive fields, a vector @arg v must be provided. Passive 802d7b241e6Sjeremylt fields can inputs or outputs (updated in-place when operator is applied). 803d7b241e6Sjeremylt 804d7b241e6Sjeremylt Active fields must be specified using this function, but their data (in a 805d7b241e6Sjeremylt CeedVector) is passed in CeedOperatorApply(). There can be at most one active 806d7b241e6Sjeremylt input and at most one active output. 807d7b241e6Sjeremylt 8088c91a0c9SJeremy L Thompson @param op CeedOperator on which to provide the field 8098795c945Sjeremylt @param fieldname Name of the field (to be matched with the name used by 8108795c945Sjeremylt CeedQFunction) 811b11c1e72Sjeremylt @param r CeedElemRestriction 8124cc79fe7SJed Brown @param b CeedBasis in which the field resides or @ref CEED_BASIS_COLLOCATED 813b11c1e72Sjeremylt if collocated with quadrature points 8144cc79fe7SJed Brown @param v CeedVector to be used by CeedOperator or @ref CEED_VECTOR_ACTIVE 8154cc79fe7SJed Brown if field is active or @ref CEED_VECTOR_NONE if using 8164cc79fe7SJed Brown @ref CEED_EVAL_WEIGHT in the QFunction 817b11c1e72Sjeremylt 818b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 819dfdf5a53Sjeremylt 8207a982d89SJeremy L. Thompson @ref User 821b11c1e72Sjeremylt **/ 822d7b241e6Sjeremylt int CeedOperatorSetField(CeedOperator op, const char *fieldname, 823a8d32208Sjeremylt CeedElemRestriction r, CeedBasis b, CeedVector v) { 824d7b241e6Sjeremylt int ierr; 82552d6035fSJeremy L Thompson if (op->composite) 826c042f62fSJeremy L Thompson // LCOV_EXCL_START 82752d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Cannot add field to composite operator."); 828c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 8298b067b84SJed Brown if (!r) 830c042f62fSJeremy L Thompson // LCOV_EXCL_START 831c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, 832c042f62fSJeremy L Thompson "ElemRestriction r for field \"%s\" must be non-NULL.", 833c042f62fSJeremy L Thompson fieldname); 834c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 8358b067b84SJed Brown if (!b) 836c042f62fSJeremy L Thompson // LCOV_EXCL_START 837c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Basis b for field \"%s\" must be non-NULL.", 838c042f62fSJeremy L Thompson fieldname); 839c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 8408b067b84SJed Brown if (!v) 841c042f62fSJeremy L Thompson // LCOV_EXCL_START 842c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Vector v for field \"%s\" must be non-NULL.", 843c042f62fSJeremy L Thompson fieldname); 844c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 84552d6035fSJeremy L Thompson 846d7b241e6Sjeremylt CeedInt numelements; 847d7b241e6Sjeremylt ierr = CeedElemRestrictionGetNumElements(r, &numelements); CeedChk(ierr); 84815910d16Sjeremylt if (r != CEED_ELEMRESTRICTION_NONE && op->hasrestriction && 84915910d16Sjeremylt op->numelements != numelements) 850c042f62fSJeremy L Thompson // LCOV_EXCL_START 851d7b241e6Sjeremylt return CeedError(op->ceed, 1, 8521d102b48SJeremy L Thompson "ElemRestriction with %d elements incompatible with prior " 8531d102b48SJeremy L Thompson "%d elements", numelements, op->numelements); 854c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 85515910d16Sjeremylt if (r != CEED_ELEMRESTRICTION_NONE) { 856d7b241e6Sjeremylt op->numelements = numelements; 8572cb0afc5Sjeremylt op->hasrestriction = true; // Restriction set, but numelements may be 0 85815910d16Sjeremylt } 859d7b241e6Sjeremylt 860783c99b3SValeria Barra if (b != CEED_BASIS_COLLOCATED) { 861d7b241e6Sjeremylt CeedInt numqpoints; 862d7b241e6Sjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &numqpoints); CeedChk(ierr); 863d7b241e6Sjeremylt if (op->numqpoints && op->numqpoints != numqpoints) 864c042f62fSJeremy L Thompson // LCOV_EXCL_START 8651d102b48SJeremy L Thompson return CeedError(op->ceed, 1, "Basis with %d quadrature points " 8661d102b48SJeremy L Thompson "incompatible with prior %d points", numqpoints, 8671d102b48SJeremy L Thompson op->numqpoints); 868c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 869d7b241e6Sjeremylt op->numqpoints = numqpoints; 870d7b241e6Sjeremylt } 87115910d16Sjeremylt CeedQFunctionField qfield; 872d1bcdac9Sjeremylt CeedOperatorField *ofield; 873d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numinputfields; i++) { 874fe2413ffSjeremylt if (!strcmp(fieldname, (*op->qf->inputfields[i]).fieldname)) { 87515910d16Sjeremylt qfield = op->qf->inputfields[i]; 876d7b241e6Sjeremylt ofield = &op->inputfields[i]; 877d7b241e6Sjeremylt goto found; 878d7b241e6Sjeremylt } 879d7b241e6Sjeremylt } 880d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numoutputfields; i++) { 881fe2413ffSjeremylt if (!strcmp(fieldname, (*op->qf->outputfields[i]).fieldname)) { 88215910d16Sjeremylt qfield = op->qf->inputfields[i]; 883d7b241e6Sjeremylt ofield = &op->outputfields[i]; 884d7b241e6Sjeremylt goto found; 885d7b241e6Sjeremylt } 886d7b241e6Sjeremylt } 887c042f62fSJeremy L Thompson // LCOV_EXCL_START 888d7b241e6Sjeremylt return CeedError(op->ceed, 1, "QFunction has no knowledge of field '%s'", 889d7b241e6Sjeremylt fieldname); 890c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 891d7b241e6Sjeremylt found: 89215910d16Sjeremylt if (r == CEED_ELEMRESTRICTION_NONE && qfield->emode != CEED_EVAL_WEIGHT) 893b0d62198Sjeremylt // LCOV_EXCL_START 89415910d16Sjeremylt return CeedError(op->ceed, 1, "CEED_ELEMRESTRICTION_NONE can only be used " 89515910d16Sjeremylt "for a field with eval mode CEED_EVAL_WEIGHT"); 896b0d62198Sjeremylt // LCOV_EXCL_STOP 897fe2413ffSjeremylt ierr = CeedCalloc(1, ofield); CeedChk(ierr); 898fe2413ffSjeremylt (*ofield)->Erestrict = r; 89971352a93Sjeremylt r->refcount += 1; 900fe2413ffSjeremylt (*ofield)->basis = b; 90171352a93Sjeremylt if (b != CEED_BASIS_COLLOCATED) 90271352a93Sjeremylt b->refcount += 1; 903fe2413ffSjeremylt (*ofield)->vec = v; 90471352a93Sjeremylt if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE) 90571352a93Sjeremylt v->refcount += 1; 906d7b241e6Sjeremylt op->nfields += 1; 907d99fa3c5SJeremy L Thompson 908d99fa3c5SJeremy L Thompson size_t len = strlen(fieldname); 909d99fa3c5SJeremy L Thompson char *tmp; 910d99fa3c5SJeremy L Thompson ierr = CeedCalloc(len+1, &tmp); CeedChk(ierr); 911d99fa3c5SJeremy L Thompson memcpy(tmp, fieldname, len+1); 912d99fa3c5SJeremy L Thompson (*ofield)->fieldname = tmp; 913d7b241e6Sjeremylt return 0; 914d7b241e6Sjeremylt } 915d7b241e6Sjeremylt 916d7b241e6Sjeremylt /** 91752d6035fSJeremy L Thompson @brief Add a sub-operator to a composite CeedOperator 918288c0443SJeremy L Thompson 91934138859Sjeremylt @param[out] compositeop Composite CeedOperator 92034138859Sjeremylt @param subop Sub-operator CeedOperator 92152d6035fSJeremy L Thompson 92252d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 92352d6035fSJeremy L Thompson 9247a982d89SJeremy L. Thompson @ref User 92552d6035fSJeremy L Thompson */ 926692c2638Sjeremylt int CeedCompositeOperatorAddSub(CeedOperator compositeop, CeedOperator subop) { 92752d6035fSJeremy L Thompson if (!compositeop->composite) 928c042f62fSJeremy L Thompson // LCOV_EXCL_START 9291d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "CeedOperator is not a composite " 9301d102b48SJeremy L Thompson "operator"); 931c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 93252d6035fSJeremy L Thompson 93352d6035fSJeremy L Thompson if (compositeop->numsub == CEED_COMPOSITE_MAX) 934c042f62fSJeremy L Thompson // LCOV_EXCL_START 9351d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "Cannot add additional suboperators"); 936c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 93752d6035fSJeremy L Thompson 93852d6035fSJeremy L Thompson compositeop->suboperators[compositeop->numsub] = subop; 93952d6035fSJeremy L Thompson subop->refcount++; 94052d6035fSJeremy L Thompson compositeop->numsub++; 94152d6035fSJeremy L Thompson return 0; 94252d6035fSJeremy L Thompson } 94352d6035fSJeremy L Thompson 94452d6035fSJeremy L Thompson /** 9451d102b48SJeremy L Thompson @brief Assemble a linear CeedQFunction associated with a CeedOperator 9461d102b48SJeremy L Thompson 9471d102b48SJeremy L Thompson This returns a CeedVector containing a matrix at each quadrature point 9481d102b48SJeremy L Thompson providing the action of the CeedQFunction associated with the CeedOperator. 9491d102b48SJeremy L Thompson The vector 'assembled' is of shape 9501d102b48SJeremy L Thompson [num_elements, num_input_fields, num_output_fields, num_quad_points] 9511d102b48SJeremy L Thompson and contains column-major matrices representing the action of the 9521d102b48SJeremy L Thompson CeedQFunction for a corresponding quadrature point on an element. Inputs and 9531d102b48SJeremy L Thompson outputs are in the order provided by the user when adding CeedOperator fields. 9544cc79fe7SJed Brown For example, a CeedQFunction with inputs 'u' and 'gradu' and outputs 'gradv' and 9551d102b48SJeremy L Thompson 'v', provided in that order, would result in an assembled QFunction that 9561d102b48SJeremy L Thompson consists of (1 + dim) x (dim + 1) matrices at each quadrature point acting 9571d102b48SJeremy L Thompson on the input [u, du_0, du_1] and producing the output [dv_0, dv_1, v]. 9581d102b48SJeremy L Thompson 9591d102b48SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 9601d102b48SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedQFunction at 9611d102b48SJeremy L Thompson quadrature points 9621d102b48SJeremy L Thompson @param[out] rstr CeedElemRestriction for CeedVector containing assembled 9631d102b48SJeremy L Thompson CeedQFunction 9641d102b48SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 9654cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 9661d102b48SJeremy L Thompson 9671d102b48SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 9681d102b48SJeremy L Thompson 9697a982d89SJeremy L. Thompson @ref User 9701d102b48SJeremy L Thompson **/ 97180ac2e43SJeremy L Thompson int CeedOperatorLinearAssembleQFunction(CeedOperator op, CeedVector *assembled, 9727f823360Sjeremylt CeedElemRestriction *rstr, 9737f823360Sjeremylt CeedRequest *request) { 9741d102b48SJeremy L Thompson int ierr; 9751d102b48SJeremy L Thompson Ceed ceed = op->ceed; 976250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 9771d102b48SJeremy L Thompson 9787172caadSjeremylt // Backend version 97980ac2e43SJeremy L Thompson if (op->LinearAssembleQFunction) { 98080ac2e43SJeremy L Thompson ierr = op->LinearAssembleQFunction(op, assembled, rstr, request); 9811d102b48SJeremy L Thompson CeedChk(ierr); 9825107b09fSJeremy L Thompson } else { 9835107b09fSJeremy L Thompson // Fallback to reference Ceed 9845107b09fSJeremy L Thompson if (!op->opfallback) { 9855107b09fSJeremy L Thompson ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 9865107b09fSJeremy L Thompson } 9875107b09fSJeremy L Thompson // Assemble 98880ac2e43SJeremy L Thompson ierr = op->opfallback->LinearAssembleQFunction(op->opfallback, assembled, 9895107b09fSJeremy L Thompson rstr, request); CeedChk(ierr); 9905107b09fSJeremy L Thompson } 991250756a7Sjeremylt 9921d102b48SJeremy L Thompson return 0; 9931d102b48SJeremy L Thompson } 9941d102b48SJeremy L Thompson 9951d102b48SJeremy L Thompson /** 996d965c7a7SJeremy L Thompson @brief Assemble the diagonal of a square linear CeedOperator 997b7ec98d8SJeremy L Thompson 9989e9210b8SJeremy L Thompson This overwrites a CeedVector with the diagonal of a linear CeedOperator. 999b7ec98d8SJeremy L Thompson 1000c04a41a7SJeremy L Thompson Note: Currently only non-composite CeedOperators with a single field and 1001c04a41a7SJeremy L Thompson composite CeedOperators with single field sub-operators are supported. 1002d965c7a7SJeremy L Thompson 1003b7ec98d8SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 1004b7ec98d8SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedOperator diagonal 1005b7ec98d8SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 10064cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1007b7ec98d8SJeremy L Thompson 1008b7ec98d8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1009b7ec98d8SJeremy L Thompson 10107a982d89SJeremy L. Thompson @ref User 1011b7ec98d8SJeremy L Thompson **/ 10122bba3ffaSJeremy L Thompson int CeedOperatorLinearAssembleDiagonal(CeedOperator op, CeedVector assembled, 10137f823360Sjeremylt CeedRequest *request) { 1014b7ec98d8SJeremy L Thompson int ierr; 1015b7ec98d8SJeremy L Thompson Ceed ceed = op->ceed; 1016250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 1017b7ec98d8SJeremy L Thompson 1018b7ec98d8SJeremy L Thompson // Use backend version, if available 101980ac2e43SJeremy L Thompson if (op->LinearAssembleDiagonal) { 102080ac2e43SJeremy L Thompson ierr = op->LinearAssembleDiagonal(op, assembled, request); CeedChk(ierr); 10219e9210b8SJeremy L Thompson } else if (op->LinearAssembleAddDiagonal) { 10229e9210b8SJeremy L Thompson ierr = CeedVectorSetValue(assembled, 0.0); CeedChk(ierr); 10239e9210b8SJeremy L Thompson return CeedOperatorLinearAssembleAddDiagonal(op, assembled, request); 10249e9210b8SJeremy L Thompson } else { 10259e9210b8SJeremy L Thompson // Fallback to reference Ceed 10269e9210b8SJeremy L Thompson if (!op->opfallback) { 10279e9210b8SJeremy L Thompson ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 10289e9210b8SJeremy L Thompson } 10299e9210b8SJeremy L Thompson // Assemble 10309e9210b8SJeremy L Thompson if (op->opfallback->LinearAssembleDiagonal) { 10319e9210b8SJeremy L Thompson ierr = op->opfallback->LinearAssembleDiagonal(op->opfallback, assembled, 10329e9210b8SJeremy L Thompson request); CeedChk(ierr); 10339e9210b8SJeremy L Thompson } else { 10349e9210b8SJeremy L Thompson ierr = CeedVectorSetValue(assembled, 0.0); CeedChk(ierr); 10359e9210b8SJeremy L Thompson return CeedOperatorLinearAssembleAddDiagonal(op, assembled, request); 10369e9210b8SJeremy L Thompson } 10379e9210b8SJeremy L Thompson } 10389e9210b8SJeremy L Thompson 10399e9210b8SJeremy L Thompson return 0; 10409e9210b8SJeremy L Thompson } 10419e9210b8SJeremy L Thompson 10429e9210b8SJeremy L Thompson /** 10439e9210b8SJeremy L Thompson @brief Assemble the diagonal of a square linear CeedOperator 10449e9210b8SJeremy L Thompson 10459e9210b8SJeremy L Thompson This sums into a CeedVector the diagonal of a linear CeedOperator. 10469e9210b8SJeremy L Thompson 10479e9210b8SJeremy L Thompson Note: Currently only non-composite CeedOperators with a single field and 10489e9210b8SJeremy L Thompson composite CeedOperators with single field sub-operators are supported. 10499e9210b8SJeremy L Thompson 10509e9210b8SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 10519e9210b8SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedOperator diagonal 10529e9210b8SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 10539e9210b8SJeremy L Thompson @ref CEED_REQUEST_IMMEDIATE 10549e9210b8SJeremy L Thompson 10559e9210b8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 10569e9210b8SJeremy L Thompson 10579e9210b8SJeremy L Thompson @ref User 10589e9210b8SJeremy L Thompson **/ 10599e9210b8SJeremy L Thompson int CeedOperatorLinearAssembleAddDiagonal(CeedOperator op, CeedVector assembled, 10609e9210b8SJeremy L Thompson CeedRequest *request) { 10619e9210b8SJeremy L Thompson int ierr; 10629e9210b8SJeremy L Thompson Ceed ceed = op->ceed; 10639e9210b8SJeremy L Thompson ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 10649e9210b8SJeremy L Thompson 10659e9210b8SJeremy L Thompson // Use backend version, if available 10669e9210b8SJeremy L Thompson if (op->LinearAssembleAddDiagonal) { 10679e9210b8SJeremy L Thompson ierr = op->LinearAssembleAddDiagonal(op, assembled, request); CeedChk(ierr); 10687172caadSjeremylt } else { 10697172caadSjeremylt // Fallback to reference Ceed 10707172caadSjeremylt if (!op->opfallback) { 10717172caadSjeremylt ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 1072b7ec98d8SJeremy L Thompson } 10737172caadSjeremylt // Assemble 10749e9210b8SJeremy L Thompson ierr = op->opfallback->LinearAssembleAddDiagonal(op->opfallback, assembled, 10757172caadSjeremylt request); CeedChk(ierr); 1076b7ec98d8SJeremy L Thompson } 1077b7ec98d8SJeremy L Thompson 1078b7ec98d8SJeremy L Thompson return 0; 1079b7ec98d8SJeremy L Thompson } 1080b7ec98d8SJeremy L Thompson 1081b7ec98d8SJeremy L Thompson /** 1082d965c7a7SJeremy L Thompson @brief Assemble the point block diagonal of a square linear CeedOperator 1083d965c7a7SJeremy L Thompson 10849e9210b8SJeremy L Thompson This overwrites a CeedVector with the point block diagonal of a linear 1085d965c7a7SJeremy L Thompson CeedOperator. 1086d965c7a7SJeremy L Thompson 1087c04a41a7SJeremy L Thompson Note: Currently only non-composite CeedOperators with a single field and 1088c04a41a7SJeremy L Thompson composite CeedOperators with single field sub-operators are supported. 1089d965c7a7SJeremy L Thompson 1090d965c7a7SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 1091d965c7a7SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedOperator point block 1092d965c7a7SJeremy L Thompson diagonal, provided in row-major form with an 1093d965c7a7SJeremy L Thompson @a ncomp * @a ncomp block at each node. The dimensions 1094d965c7a7SJeremy L Thompson of this vector are derived from the active vector 1095d965c7a7SJeremy L Thompson for the CeedOperator. The array has shape 1096d965c7a7SJeremy L Thompson [nodes, component out, component in]. 1097d965c7a7SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 1098d965c7a7SJeremy L Thompson CEED_REQUEST_IMMEDIATE 1099d965c7a7SJeremy L Thompson 1100d965c7a7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1101d965c7a7SJeremy L Thompson 1102d965c7a7SJeremy L Thompson @ref User 1103d965c7a7SJeremy L Thompson **/ 110480ac2e43SJeremy L Thompson int CeedOperatorLinearAssemblePointBlockDiagonal(CeedOperator op, 11052bba3ffaSJeremy L Thompson CeedVector assembled, CeedRequest *request) { 1106d965c7a7SJeremy L Thompson int ierr; 1107d965c7a7SJeremy L Thompson Ceed ceed = op->ceed; 1108d965c7a7SJeremy L Thompson ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 1109d965c7a7SJeremy L Thompson 1110d965c7a7SJeremy L Thompson // Use backend version, if available 111180ac2e43SJeremy L Thompson if (op->LinearAssemblePointBlockDiagonal) { 111280ac2e43SJeremy L Thompson ierr = op->LinearAssemblePointBlockDiagonal(op, assembled, request); 1113d965c7a7SJeremy L Thompson CeedChk(ierr); 11149e9210b8SJeremy L Thompson } else if (op->LinearAssembleAddPointBlockDiagonal) { 11159e9210b8SJeremy L Thompson ierr = CeedVectorSetValue(assembled, 0.0); CeedChk(ierr); 11169e9210b8SJeremy L Thompson return CeedOperatorLinearAssembleAddPointBlockDiagonal(op, assembled, 11179e9210b8SJeremy L Thompson request); 1118d965c7a7SJeremy L Thompson } else { 1119d965c7a7SJeremy L Thompson // Fallback to reference Ceed 1120d965c7a7SJeremy L Thompson if (!op->opfallback) { 1121d965c7a7SJeremy L Thompson ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 1122d965c7a7SJeremy L Thompson } 1123d965c7a7SJeremy L Thompson // Assemble 11249e9210b8SJeremy L Thompson if (op->opfallback->LinearAssemblePointBlockDiagonal) { 112580ac2e43SJeremy L Thompson ierr = op->opfallback->LinearAssemblePointBlockDiagonal(op->opfallback, 1126d965c7a7SJeremy L Thompson assembled, request); CeedChk(ierr); 11279e9210b8SJeremy L Thompson } else { 11289e9210b8SJeremy L Thompson ierr = CeedVectorSetValue(assembled, 0.0); CeedChk(ierr); 11299e9210b8SJeremy L Thompson return CeedOperatorLinearAssembleAddPointBlockDiagonal(op, assembled, 11309e9210b8SJeremy L Thompson request); 11319e9210b8SJeremy L Thompson } 11329e9210b8SJeremy L Thompson } 11339e9210b8SJeremy L Thompson 11349e9210b8SJeremy L Thompson return 0; 11359e9210b8SJeremy L Thompson } 11369e9210b8SJeremy L Thompson 11379e9210b8SJeremy L Thompson /** 11389e9210b8SJeremy L Thompson @brief Assemble the point block diagonal of a square linear CeedOperator 11399e9210b8SJeremy L Thompson 11409e9210b8SJeremy L Thompson This sums into a CeedVector with the point block diagonal of a linear 11419e9210b8SJeremy L Thompson CeedOperator. 11429e9210b8SJeremy L Thompson 11439e9210b8SJeremy L Thompson Note: Currently only non-composite CeedOperators with a single field and 11449e9210b8SJeremy L Thompson composite CeedOperators with single field sub-operators are supported. 11459e9210b8SJeremy L Thompson 11469e9210b8SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 11479e9210b8SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedOperator point block 11489e9210b8SJeremy L Thompson diagonal, provided in row-major form with an 11499e9210b8SJeremy L Thompson @a ncomp * @a ncomp block at each node. The dimensions 11509e9210b8SJeremy L Thompson of this vector are derived from the active vector 11519e9210b8SJeremy L Thompson for the CeedOperator. The array has shape 11529e9210b8SJeremy L Thompson [nodes, component out, component in]. 11539e9210b8SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 11549e9210b8SJeremy L Thompson CEED_REQUEST_IMMEDIATE 11559e9210b8SJeremy L Thompson 11569e9210b8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 11579e9210b8SJeremy L Thompson 11589e9210b8SJeremy L Thompson @ref User 11599e9210b8SJeremy L Thompson **/ 11609e9210b8SJeremy L Thompson int CeedOperatorLinearAssembleAddPointBlockDiagonal(CeedOperator op, 11619e9210b8SJeremy L Thompson CeedVector assembled, CeedRequest *request) { 11629e9210b8SJeremy L Thompson int ierr; 11639e9210b8SJeremy L Thompson Ceed ceed = op->ceed; 11649e9210b8SJeremy L Thompson ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 11659e9210b8SJeremy L Thompson 11669e9210b8SJeremy L Thompson // Use backend version, if available 11679e9210b8SJeremy L Thompson if (op->LinearAssembleAddPointBlockDiagonal) { 11689e9210b8SJeremy L Thompson ierr = op->LinearAssembleAddPointBlockDiagonal(op, assembled, request); 11699e9210b8SJeremy L Thompson CeedChk(ierr); 11709e9210b8SJeremy L Thompson } else { 11719e9210b8SJeremy L Thompson // Fallback to reference Ceed 11729e9210b8SJeremy L Thompson if (!op->opfallback) { 11739e9210b8SJeremy L Thompson ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 11749e9210b8SJeremy L Thompson } 11759e9210b8SJeremy L Thompson // Assemble 11769e9210b8SJeremy L Thompson ierr = op->opfallback->LinearAssembleAddPointBlockDiagonal(op->opfallback, 11779e9210b8SJeremy L Thompson assembled, request); CeedChk(ierr); 1178d965c7a7SJeremy L Thompson } 1179d965c7a7SJeremy L Thompson 1180d965c7a7SJeremy L Thompson return 0; 1181d965c7a7SJeremy L Thompson } 1182d965c7a7SJeremy L Thompson 1183d965c7a7SJeremy L Thompson /** 1184d99fa3c5SJeremy L Thompson @brief Create a multigrid coarse operator and level transfer operators 1185d99fa3c5SJeremy L Thompson for a CeedOperator, creating the prolongation basis from the 1186d99fa3c5SJeremy L Thompson fine and coarse grid interpolation 1187d99fa3c5SJeremy L Thompson 1188d99fa3c5SJeremy L Thompson @param[in] opFine Fine grid operator 1189d99fa3c5SJeremy L Thompson @param[in] PMultFine L-vector multiplicity in parallel gather/scatter 1190d99fa3c5SJeremy L Thompson @param[in] rstrCoarse Coarse grid restriction 1191d99fa3c5SJeremy L Thompson @param[in] basisCoarse Coarse grid active vector basis 1192d99fa3c5SJeremy L Thompson @param[out] opCoarse Coarse grid operator 1193d99fa3c5SJeremy L Thompson @param[out] opProlong Coarse to fine operator 1194d99fa3c5SJeremy L Thompson @param[out] opRestrict Fine to coarse operator 1195d99fa3c5SJeremy L Thompson 1196d99fa3c5SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1197d99fa3c5SJeremy L Thompson 1198d99fa3c5SJeremy L Thompson @ref User 1199d99fa3c5SJeremy L Thompson **/ 1200d99fa3c5SJeremy L Thompson int CeedOperatorMultigridLevelCreate(CeedOperator opFine, CeedVector PMultFine, 1201d99fa3c5SJeremy L Thompson CeedElemRestriction rstrCoarse, CeedBasis basisCoarse, 1202d99fa3c5SJeremy L Thompson CeedOperator *opCoarse, CeedOperator *opProlong, CeedOperator *opRestrict) { 1203d99fa3c5SJeremy L Thompson int ierr; 1204d99fa3c5SJeremy L Thompson Ceed ceed; 1205d99fa3c5SJeremy L Thompson ierr = CeedOperatorGetCeed(opFine, &ceed); CeedChk(ierr); 1206d99fa3c5SJeremy L Thompson 1207d99fa3c5SJeremy L Thompson // Check for compatible quadrature spaces 1208d99fa3c5SJeremy L Thompson CeedBasis basisFine; 1209d99fa3c5SJeremy L Thompson ierr = CeedOperatorGetActiveBasis(opFine, &basisFine); CeedChk(ierr); 1210d99fa3c5SJeremy L Thompson CeedInt Qf, Qc; 1211d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumQuadraturePoints(basisFine, &Qf); CeedChk(ierr); 1212d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumQuadraturePoints(basisCoarse, &Qc); CeedChk(ierr); 1213d99fa3c5SJeremy L Thompson if (Qf != Qc) 1214d99fa3c5SJeremy L Thompson // LCOV_EXCL_START 1215d99fa3c5SJeremy L Thompson return CeedError(ceed, 1, "Bases must have compatible quadrature spaces"); 1216d99fa3c5SJeremy L Thompson // LCOV_EXCL_STOP 1217d99fa3c5SJeremy L Thompson 1218d99fa3c5SJeremy L Thompson // Coarse to fine basis 1219d99fa3c5SJeremy L Thompson CeedInt Pf, Pc, Q = Qf; 1220d99fa3c5SJeremy L Thompson bool isTensorF, isTensorC; 1221d99fa3c5SJeremy L Thompson ierr = CeedBasisIsTensor(basisFine, &isTensorF); CeedChk(ierr); 1222d99fa3c5SJeremy L Thompson ierr = CeedBasisIsTensor(basisCoarse, &isTensorC); CeedChk(ierr); 1223d99fa3c5SJeremy L Thompson CeedScalar *interpC, *interpF, *interpCtoF, *tau; 1224d99fa3c5SJeremy L Thompson if (isTensorF && isTensorC) { 1225d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumNodes1D(basisFine, &Pf); CeedChk(ierr); 1226d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumNodes1D(basisCoarse, &Pc); CeedChk(ierr); 1227d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumQuadraturePoints1D(basisCoarse, &Q); CeedChk(ierr); 1228d99fa3c5SJeremy L Thompson } else if (!isTensorF && !isTensorC) { 1229d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumNodes(basisFine, &Pf); CeedChk(ierr); 1230d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumNodes(basisCoarse, &Pc); CeedChk(ierr); 1231d99fa3c5SJeremy L Thompson } else { 1232d99fa3c5SJeremy L Thompson // LCOV_EXCL_START 1233d99fa3c5SJeremy L Thompson return CeedError(ceed, 1, "Bases must both be tensor or non-tensor"); 1234d99fa3c5SJeremy L Thompson // LCOV_EXCL_STOP 1235d99fa3c5SJeremy L Thompson } 1236d99fa3c5SJeremy L Thompson 1237d99fa3c5SJeremy L Thompson ierr = CeedMalloc(Q*Pf, &interpF); CeedChk(ierr); 1238d99fa3c5SJeremy L Thompson ierr = CeedMalloc(Q*Pc, &interpC); CeedChk(ierr); 1239d99fa3c5SJeremy L Thompson ierr = CeedCalloc(Pc*Pf, &interpCtoF); CeedChk(ierr); 1240d99fa3c5SJeremy L Thompson ierr = CeedMalloc(Q, &tau); CeedChk(ierr); 1241d99fa3c5SJeremy L Thompson if (isTensorF) { 1242d99fa3c5SJeremy L Thompson memcpy(interpF, basisFine->interp1d, Q*Pf*sizeof basisFine->interp1d[0]); 1243d99fa3c5SJeremy L Thompson memcpy(interpC, basisCoarse->interp1d, Q*Pc*sizeof basisCoarse->interp1d[0]); 1244d99fa3c5SJeremy L Thompson } else { 1245d99fa3c5SJeremy L Thompson memcpy(interpF, basisFine->interp, Q*Pf*sizeof basisFine->interp[0]); 1246d99fa3c5SJeremy L Thompson memcpy(interpC, basisCoarse->interp, Q*Pc*sizeof basisCoarse->interp[0]); 1247d99fa3c5SJeremy L Thompson } 1248d99fa3c5SJeremy L Thompson 1249d99fa3c5SJeremy L Thompson // -- QR Factorization, interpF = Q R 1250d99fa3c5SJeremy L Thompson ierr = CeedQRFactorization(ceed, interpF, tau, Q, Pf); CeedChk(ierr); 1251d99fa3c5SJeremy L Thompson 1252d99fa3c5SJeremy L Thompson // -- Apply Qtranspose, interpC = Qtranspose interpC 1253d99fa3c5SJeremy L Thompson CeedHouseholderApplyQ(interpC, interpF, tau, CEED_TRANSPOSE, 1254d99fa3c5SJeremy L Thompson Q, Pc, Pf, Pc, 1); 1255d99fa3c5SJeremy L Thompson 1256d99fa3c5SJeremy L Thompson // -- Apply Rinv, interpCtoF = Rinv interpC 1257d99fa3c5SJeremy L Thompson for (CeedInt j=0; j<Pc; j++) { // Column j 1258d99fa3c5SJeremy L Thompson interpCtoF[j+Pc*(Pf-1)] = interpC[j+Pc*(Pf-1)]/interpF[Pf*Pf-1]; 1259d99fa3c5SJeremy L Thompson for (CeedInt i=Pf-2; i>=0; i--) { // Row i 1260d99fa3c5SJeremy L Thompson interpCtoF[j+Pc*i] = interpC[j+Pc*i]; 1261d99fa3c5SJeremy L Thompson for (CeedInt k=i+1; k<Pf; k++) 1262d99fa3c5SJeremy L Thompson interpCtoF[j+Pc*i] -= interpF[k+Pf*i]*interpCtoF[j+Pc*k]; 1263d99fa3c5SJeremy L Thompson interpCtoF[j+Pc*i] /= interpF[i+Pf*i]; 1264d99fa3c5SJeremy L Thompson } 1265d99fa3c5SJeremy L Thompson } 1266d99fa3c5SJeremy L Thompson ierr = CeedFree(&tau); CeedChk(ierr); 1267d99fa3c5SJeremy L Thompson ierr = CeedFree(&interpC); CeedChk(ierr); 1268d99fa3c5SJeremy L Thompson ierr = CeedFree(&interpF); CeedChk(ierr); 1269d99fa3c5SJeremy L Thompson 1270d99fa3c5SJeremy L Thompson // Fallback to interpCtoF versions of code 1271d99fa3c5SJeremy L Thompson if (isTensorF) { 1272d99fa3c5SJeremy L Thompson ierr = CeedOperatorMultigridLevelCreateTensorH1(opFine, PMultFine, 1273d99fa3c5SJeremy L Thompson rstrCoarse, basisCoarse, interpCtoF, opCoarse, opProlong, opRestrict); 1274d99fa3c5SJeremy L Thompson CeedChk(ierr); 1275d99fa3c5SJeremy L Thompson } else { 1276d99fa3c5SJeremy L Thompson ierr = CeedOperatorMultigridLevelCreateH1(opFine, PMultFine, 1277d99fa3c5SJeremy L Thompson rstrCoarse, basisCoarse, interpCtoF, opCoarse, opProlong, opRestrict); 1278d99fa3c5SJeremy L Thompson CeedChk(ierr); 1279d99fa3c5SJeremy L Thompson } 1280d99fa3c5SJeremy L Thompson 1281d99fa3c5SJeremy L Thompson // Cleanup 1282d99fa3c5SJeremy L Thompson ierr = CeedFree(&interpCtoF); CeedChk(ierr); 1283d99fa3c5SJeremy L Thompson return 0; 1284d99fa3c5SJeremy L Thompson } 1285d99fa3c5SJeremy L Thompson 1286d99fa3c5SJeremy L Thompson /** 1287d99fa3c5SJeremy L Thompson @brief Create a multigrid coarse operator and level transfer operators 1288d99fa3c5SJeremy L Thompson for a CeedOperator with a tensor basis for the active basis 1289d99fa3c5SJeremy L Thompson 1290d99fa3c5SJeremy L Thompson @param[in] opFine Fine grid operator 1291d99fa3c5SJeremy L Thompson @param[in] PMultFine L-vector multiplicity in parallel gather/scatter 1292d99fa3c5SJeremy L Thompson @param[in] rstrCoarse Coarse grid restriction 1293d99fa3c5SJeremy L Thompson @param[in] basisCoarse Coarse grid active vector basis 1294d99fa3c5SJeremy L Thompson @param[in] interpCtoF Matrix for coarse to fine interpolation 1295d99fa3c5SJeremy L Thompson @param[out] opCoarse Coarse grid operator 1296d99fa3c5SJeremy L Thompson @param[out] opProlong Coarse to fine operator 1297d99fa3c5SJeremy L Thompson @param[out] opRestrict Fine to coarse operator 1298d99fa3c5SJeremy L Thompson 1299d99fa3c5SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1300d99fa3c5SJeremy L Thompson 1301d99fa3c5SJeremy L Thompson @ref User 1302d99fa3c5SJeremy L Thompson **/ 1303d99fa3c5SJeremy L Thompson int CeedOperatorMultigridLevelCreateTensorH1(CeedOperator opFine, 1304d99fa3c5SJeremy L Thompson CeedVector PMultFine, CeedElemRestriction rstrCoarse, CeedBasis basisCoarse, 1305d99fa3c5SJeremy L Thompson const CeedScalar *interpCtoF, CeedOperator *opCoarse, 1306d99fa3c5SJeremy L Thompson CeedOperator *opProlong, CeedOperator *opRestrict) { 1307d99fa3c5SJeremy L Thompson int ierr; 1308d99fa3c5SJeremy L Thompson Ceed ceed; 1309d99fa3c5SJeremy L Thompson ierr = CeedOperatorGetCeed(opFine, &ceed); CeedChk(ierr); 1310d99fa3c5SJeremy L Thompson 1311d99fa3c5SJeremy L Thompson // Check for compatible quadrature spaces 1312d99fa3c5SJeremy L Thompson CeedBasis basisFine; 1313d99fa3c5SJeremy L Thompson ierr = CeedOperatorGetActiveBasis(opFine, &basisFine); CeedChk(ierr); 1314d99fa3c5SJeremy L Thompson CeedInt Qf, Qc; 1315d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumQuadraturePoints(basisFine, &Qf); CeedChk(ierr); 1316d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumQuadraturePoints(basisCoarse, &Qc); CeedChk(ierr); 1317d99fa3c5SJeremy L Thompson if (Qf != Qc) 1318d99fa3c5SJeremy L Thompson // LCOV_EXCL_START 1319d99fa3c5SJeremy L Thompson return CeedError(ceed, 1, "Bases must have compatible quadrature spaces"); 1320d99fa3c5SJeremy L Thompson // LCOV_EXCL_STOP 1321d99fa3c5SJeremy L Thompson 1322d99fa3c5SJeremy L Thompson // Coarse to fine basis 1323d99fa3c5SJeremy L Thompson CeedInt dim, ncomp, nnodesCoarse, P1dFine, P1dCoarse; 1324d99fa3c5SJeremy L Thompson ierr = CeedBasisGetDimension(basisFine, &dim); CeedChk(ierr); 1325d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumComponents(basisFine, &ncomp); CeedChk(ierr); 1326d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumNodes1D(basisFine, &P1dFine); CeedChk(ierr); 1327d99fa3c5SJeremy L Thompson ierr = CeedElemRestrictionGetElementSize(rstrCoarse, &nnodesCoarse); 1328d99fa3c5SJeremy L Thompson CeedChk(ierr); 1329d99fa3c5SJeremy L Thompson P1dCoarse = dim == 1 ? nnodesCoarse : 1330d99fa3c5SJeremy L Thompson dim == 2 ? sqrt(nnodesCoarse) : 1331d99fa3c5SJeremy L Thompson cbrt(nnodesCoarse); 1332d99fa3c5SJeremy L Thompson CeedScalar *qref, *qweight, *grad; 1333d99fa3c5SJeremy L Thompson ierr = CeedCalloc(P1dFine, &qref); CeedChk(ierr); 1334d99fa3c5SJeremy L Thompson ierr = CeedCalloc(P1dFine, &qweight); CeedChk(ierr); 1335d99fa3c5SJeremy L Thompson ierr = CeedCalloc(P1dFine*P1dCoarse*dim, &grad); CeedChk(ierr); 1336d99fa3c5SJeremy L Thompson CeedBasis basisCtoF; 1337d99fa3c5SJeremy L Thompson ierr = CeedBasisCreateTensorH1(ceed, dim, ncomp, P1dCoarse, P1dFine, 1338d99fa3c5SJeremy L Thompson interpCtoF, grad, qref, qweight, &basisCtoF); 1339d99fa3c5SJeremy L Thompson CeedChk(ierr); 1340d99fa3c5SJeremy L Thompson ierr = CeedFree(&qref); CeedChk(ierr); 1341d99fa3c5SJeremy L Thompson ierr = CeedFree(&qweight); CeedChk(ierr); 1342d99fa3c5SJeremy L Thompson ierr = CeedFree(&grad); CeedChk(ierr); 1343d99fa3c5SJeremy L Thompson 1344d99fa3c5SJeremy L Thompson // Core code 1345d99fa3c5SJeremy L Thompson ierr = CeedOperatorMultigridLevel_Core(opFine, PMultFine, rstrCoarse, 1346d99fa3c5SJeremy L Thompson basisCoarse, basisCtoF, opCoarse, 1347d99fa3c5SJeremy L Thompson opProlong, opRestrict); 1348d99fa3c5SJeremy L Thompson CeedChk(ierr); 1349d99fa3c5SJeremy L Thompson return 0; 1350d99fa3c5SJeremy L Thompson } 1351d99fa3c5SJeremy L Thompson 1352d99fa3c5SJeremy L Thompson /** 1353d99fa3c5SJeremy L Thompson @brief Create a multigrid coarse operator and level transfer operators 1354d99fa3c5SJeremy L Thompson for a CeedOperator with a non-tensor basis for the active vector 1355d99fa3c5SJeremy L Thompson 1356d99fa3c5SJeremy L Thompson @param[in] opFine Fine grid operator 1357d99fa3c5SJeremy L Thompson @param[in] PMultFine L-vector multiplicity in parallel gather/scatter 1358d99fa3c5SJeremy L Thompson @param[in] rstrCoarse Coarse grid restriction 1359d99fa3c5SJeremy L Thompson @param[in] basisCoarse Coarse grid active vector basis 1360d99fa3c5SJeremy L Thompson @param[in] interpCtoF Matrix for coarse to fine interpolation 1361d99fa3c5SJeremy L Thompson @param[out] opCoarse Coarse grid operator 1362d99fa3c5SJeremy L Thompson @param[out] opProlong Coarse to fine operator 1363d99fa3c5SJeremy L Thompson @param[out] opRestrict Fine to coarse operator 1364d99fa3c5SJeremy L Thompson 1365d99fa3c5SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1366d99fa3c5SJeremy L Thompson 1367d99fa3c5SJeremy L Thompson @ref User 1368d99fa3c5SJeremy L Thompson **/ 1369d99fa3c5SJeremy L Thompson int CeedOperatorMultigridLevelCreateH1(CeedOperator opFine, 1370d99fa3c5SJeremy L Thompson CeedVector PMultFine, 1371d99fa3c5SJeremy L Thompson CeedElemRestriction rstrCoarse, 1372d99fa3c5SJeremy L Thompson CeedBasis basisCoarse, 1373d99fa3c5SJeremy L Thompson const CeedScalar *interpCtoF, 1374d99fa3c5SJeremy L Thompson CeedOperator *opCoarse, 1375d99fa3c5SJeremy L Thompson CeedOperator *opProlong, 1376d99fa3c5SJeremy L Thompson CeedOperator *opRestrict) { 1377d99fa3c5SJeremy L Thompson int ierr; 1378d99fa3c5SJeremy L Thompson Ceed ceed; 1379d99fa3c5SJeremy L Thompson ierr = CeedOperatorGetCeed(opFine, &ceed); CeedChk(ierr); 1380d99fa3c5SJeremy L Thompson 1381d99fa3c5SJeremy L Thompson // Check for compatible quadrature spaces 1382d99fa3c5SJeremy L Thompson CeedBasis basisFine; 1383d99fa3c5SJeremy L Thompson ierr = CeedOperatorGetActiveBasis(opFine, &basisFine); CeedChk(ierr); 1384d99fa3c5SJeremy L Thompson CeedInt Qf, Qc; 1385d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumQuadraturePoints(basisFine, &Qf); CeedChk(ierr); 1386d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumQuadraturePoints(basisCoarse, &Qc); CeedChk(ierr); 1387d99fa3c5SJeremy L Thompson if (Qf != Qc) 1388d99fa3c5SJeremy L Thompson // LCOV_EXCL_START 1389d99fa3c5SJeremy L Thompson return CeedError(ceed, 1, "Bases must have compatible quadrature spaces"); 1390d99fa3c5SJeremy L Thompson // LCOV_EXCL_STOP 1391d99fa3c5SJeremy L Thompson 1392d99fa3c5SJeremy L Thompson // Coarse to fine basis 1393d99fa3c5SJeremy L Thompson CeedElemTopology topo; 1394d99fa3c5SJeremy L Thompson ierr = CeedBasisGetTopology(basisFine, &topo); CeedChk(ierr); 1395d99fa3c5SJeremy L Thompson CeedInt dim, ncomp, nnodesCoarse, nnodesFine; 1396d99fa3c5SJeremy L Thompson ierr = CeedBasisGetDimension(basisFine, &dim); CeedChk(ierr); 1397d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumComponents(basisFine, &ncomp); CeedChk(ierr); 1398d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumNodes(basisFine, &nnodesFine); CeedChk(ierr); 1399d99fa3c5SJeremy L Thompson ierr = CeedElemRestrictionGetElementSize(rstrCoarse, &nnodesCoarse); 1400d99fa3c5SJeremy L Thompson CeedChk(ierr); 1401d99fa3c5SJeremy L Thompson CeedScalar *qref, *qweight, *grad; 1402d99fa3c5SJeremy L Thompson ierr = CeedCalloc(nnodesFine, &qref); CeedChk(ierr); 1403d99fa3c5SJeremy L Thompson ierr = CeedCalloc(nnodesFine, &qweight); CeedChk(ierr); 1404d99fa3c5SJeremy L Thompson ierr = CeedCalloc(nnodesFine*nnodesCoarse*dim, &grad); CeedChk(ierr); 1405d99fa3c5SJeremy L Thompson CeedBasis basisCtoF; 1406d99fa3c5SJeremy L Thompson ierr = CeedBasisCreateH1(ceed, topo, ncomp, nnodesCoarse, nnodesFine, 1407d99fa3c5SJeremy L Thompson interpCtoF, grad, qref, qweight, &basisCtoF); 1408d99fa3c5SJeremy L Thompson CeedChk(ierr); 1409d99fa3c5SJeremy L Thompson ierr = CeedFree(&qref); CeedChk(ierr); 1410d99fa3c5SJeremy L Thompson ierr = CeedFree(&qweight); CeedChk(ierr); 1411d99fa3c5SJeremy L Thompson ierr = CeedFree(&grad); CeedChk(ierr); 1412d99fa3c5SJeremy L Thompson 1413d99fa3c5SJeremy L Thompson // Core code 1414d99fa3c5SJeremy L Thompson ierr = CeedOperatorMultigridLevel_Core(opFine, PMultFine, rstrCoarse, 1415d99fa3c5SJeremy L Thompson basisCoarse, basisCtoF, opCoarse, 1416d99fa3c5SJeremy L Thompson opProlong, opRestrict); 1417d99fa3c5SJeremy L Thompson CeedChk(ierr); 1418d99fa3c5SJeremy L Thompson return 0; 1419d99fa3c5SJeremy L Thompson } 1420d99fa3c5SJeremy L Thompson 1421d99fa3c5SJeremy L Thompson /** 14223bd813ffSjeremylt @brief Build a FDM based approximate inverse for each element for a 14233bd813ffSjeremylt CeedOperator 14243bd813ffSjeremylt 14253bd813ffSjeremylt This returns a CeedOperator and CeedVector to apply a Fast Diagonalization 14263bd813ffSjeremylt Method based approximate inverse. This function obtains the simultaneous 14273bd813ffSjeremylt diagonalization for the 1D mass and Laplacian operators, 14283bd813ffSjeremylt M = V^T V, K = V^T S V. 14293bd813ffSjeremylt The assembled QFunction is used to modify the eigenvalues from simultaneous 14303bd813ffSjeremylt diagonalization and obtain an approximate inverse of the form 14313bd813ffSjeremylt V^T S^hat V. The CeedOperator must be linear and non-composite. The 14323bd813ffSjeremylt associated CeedQFunction must therefore also be linear. 14333bd813ffSjeremylt 14343bd813ffSjeremylt @param op CeedOperator to create element inverses 14353bd813ffSjeremylt @param[out] fdminv CeedOperator to apply the action of a FDM based inverse 14363bd813ffSjeremylt for each element 14373bd813ffSjeremylt @param request Address of CeedRequest for non-blocking completion, else 14384cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 14393bd813ffSjeremylt 14403bd813ffSjeremylt @return An error code: 0 - success, otherwise - failure 14413bd813ffSjeremylt 14427a982d89SJeremy L. Thompson @ref Backend 14433bd813ffSjeremylt **/ 14443bd813ffSjeremylt int CeedOperatorCreateFDMElementInverse(CeedOperator op, CeedOperator *fdminv, 14453bd813ffSjeremylt CeedRequest *request) { 14463bd813ffSjeremylt int ierr; 14473bd813ffSjeremylt Ceed ceed = op->ceed; 1448713f43c3Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 14493bd813ffSjeremylt 1450713f43c3Sjeremylt // Use backend version, if available 1451713f43c3Sjeremylt if (op->CreateFDMElementInverse) { 1452713f43c3Sjeremylt ierr = op->CreateFDMElementInverse(op, fdminv, request); CeedChk(ierr); 1453713f43c3Sjeremylt } else { 1454713f43c3Sjeremylt // Fallback to reference Ceed 1455713f43c3Sjeremylt if (!op->opfallback) { 1456713f43c3Sjeremylt ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 14573bd813ffSjeremylt } 1458713f43c3Sjeremylt // Assemble 1459713f43c3Sjeremylt ierr = op->opfallback->CreateFDMElementInverse(op->opfallback, fdminv, 14603bd813ffSjeremylt request); CeedChk(ierr); 14613bd813ffSjeremylt } 14623bd813ffSjeremylt 14633bd813ffSjeremylt return 0; 14643bd813ffSjeremylt } 14653bd813ffSjeremylt 14667a982d89SJeremy L. Thompson /** 14677a982d89SJeremy L. Thompson @brief View a CeedOperator 14687a982d89SJeremy L. Thompson 14697a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 14707a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 14717a982d89SJeremy L. Thompson 14727a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 14737a982d89SJeremy L. Thompson 14747a982d89SJeremy L. Thompson @ref User 14757a982d89SJeremy L. Thompson **/ 14767a982d89SJeremy L. Thompson int CeedOperatorView(CeedOperator op, FILE *stream) { 14777a982d89SJeremy L. Thompson int ierr; 14787a982d89SJeremy L. Thompson 14797a982d89SJeremy L. Thompson if (op->composite) { 14807a982d89SJeremy L. Thompson fprintf(stream, "Composite CeedOperator\n"); 14817a982d89SJeremy L. Thompson 14827a982d89SJeremy L. Thompson for (CeedInt i=0; i<op->numsub; i++) { 14837a982d89SJeremy L. Thompson fprintf(stream, " SubOperator [%d]:\n", i); 14847a982d89SJeremy L. Thompson ierr = CeedOperatorSingleView(op->suboperators[i], 1, stream); 14857a982d89SJeremy L. Thompson CeedChk(ierr); 14867a982d89SJeremy L. Thompson } 14877a982d89SJeremy L. Thompson } else { 14887a982d89SJeremy L. Thompson fprintf(stream, "CeedOperator\n"); 14897a982d89SJeremy L. Thompson ierr = CeedOperatorSingleView(op, 0, stream); CeedChk(ierr); 14907a982d89SJeremy L. Thompson } 14917a982d89SJeremy L. Thompson 14927a982d89SJeremy L. Thompson return 0; 14937a982d89SJeremy L. Thompson } 14943bd813ffSjeremylt 14953bd813ffSjeremylt /** 14963bd813ffSjeremylt @brief Apply CeedOperator to a vector 1497d7b241e6Sjeremylt 1498d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 1499d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 1500d7b241e6Sjeremylt CeedOperatorSetField(). 1501d7b241e6Sjeremylt 1502d7b241e6Sjeremylt @param op CeedOperator to apply 15034cc79fe7SJed Brown @param[in] in CeedVector containing input state or @ref CEED_VECTOR_NONE if 150434138859Sjeremylt there are no active inputs 1505b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 15064cc79fe7SJed Brown distinct from @a in) or @ref CEED_VECTOR_NONE if there are no 150734138859Sjeremylt active outputs 1508d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 15094cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1510b11c1e72Sjeremylt 1511b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1512dfdf5a53Sjeremylt 15137a982d89SJeremy L. Thompson @ref User 1514b11c1e72Sjeremylt **/ 1515692c2638Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, 1516692c2638Sjeremylt CeedRequest *request) { 1517d7b241e6Sjeremylt int ierr; 1518d7b241e6Sjeremylt Ceed ceed = op->ceed; 1519250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 1520d7b241e6Sjeremylt 1521250756a7Sjeremylt if (op->numelements) { 1522250756a7Sjeremylt // Standard Operator 1523cae8b89aSjeremylt if (op->Apply) { 1524250756a7Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 1525cae8b89aSjeremylt } else { 1526cae8b89aSjeremylt // Zero all output vectors 1527250756a7Sjeremylt CeedQFunction qf = op->qf; 1528cae8b89aSjeremylt for (CeedInt i=0; i<qf->numoutputfields; i++) { 1529cae8b89aSjeremylt CeedVector vec = op->outputfields[i]->vec; 1530cae8b89aSjeremylt if (vec == CEED_VECTOR_ACTIVE) 1531cae8b89aSjeremylt vec = out; 1532cae8b89aSjeremylt if (vec != CEED_VECTOR_NONE) { 1533cae8b89aSjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1534cae8b89aSjeremylt } 1535cae8b89aSjeremylt } 1536250756a7Sjeremylt // Apply 1537250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1538250756a7Sjeremylt } 1539250756a7Sjeremylt } else if (op->composite) { 1540250756a7Sjeremylt // Composite Operator 1541250756a7Sjeremylt if (op->ApplyComposite) { 1542250756a7Sjeremylt ierr = op->ApplyComposite(op, in, out, request); CeedChk(ierr); 1543250756a7Sjeremylt } else { 1544250756a7Sjeremylt CeedInt numsub; 1545250756a7Sjeremylt ierr = CeedOperatorGetNumSub(op, &numsub); CeedChk(ierr); 1546250756a7Sjeremylt CeedOperator *suboperators; 1547250756a7Sjeremylt ierr = CeedOperatorGetSubList(op, &suboperators); CeedChk(ierr); 1548250756a7Sjeremylt 1549250756a7Sjeremylt // Zero all output vectors 1550250756a7Sjeremylt if (out != CEED_VECTOR_NONE) { 1551cae8b89aSjeremylt ierr = CeedVectorSetValue(out, 0.0); CeedChk(ierr); 1552cae8b89aSjeremylt } 1553250756a7Sjeremylt for (CeedInt i=0; i<numsub; i++) { 1554250756a7Sjeremylt for (CeedInt j=0; j<suboperators[i]->qf->numoutputfields; j++) { 1555250756a7Sjeremylt CeedVector vec = suboperators[i]->outputfields[j]->vec; 1556250756a7Sjeremylt if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) { 1557250756a7Sjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1558250756a7Sjeremylt } 1559250756a7Sjeremylt } 1560250756a7Sjeremylt } 1561250756a7Sjeremylt // Apply 1562250756a7Sjeremylt for (CeedInt i=0; i<op->numsub; i++) { 1563250756a7Sjeremylt ierr = CeedOperatorApplyAdd(op->suboperators[i], in, out, request); 1564cae8b89aSjeremylt CeedChk(ierr); 1565cae8b89aSjeremylt } 1566cae8b89aSjeremylt } 1567250756a7Sjeremylt } 1568250756a7Sjeremylt 1569cae8b89aSjeremylt return 0; 1570cae8b89aSjeremylt } 1571cae8b89aSjeremylt 1572cae8b89aSjeremylt /** 1573cae8b89aSjeremylt @brief Apply CeedOperator to a vector and add result to output vector 1574cae8b89aSjeremylt 1575cae8b89aSjeremylt This computes the action of the operator on the specified (active) input, 1576cae8b89aSjeremylt yielding its (active) output. All inputs and outputs must be specified using 1577cae8b89aSjeremylt CeedOperatorSetField(). 1578cae8b89aSjeremylt 1579cae8b89aSjeremylt @param op CeedOperator to apply 1580cae8b89aSjeremylt @param[in] in CeedVector containing input state or NULL if there are no 1581cae8b89aSjeremylt active inputs 1582cae8b89aSjeremylt @param[out] out CeedVector to sum in result of applying operator (must be 1583cae8b89aSjeremylt distinct from @a in) or NULL if there are no active outputs 1584cae8b89aSjeremylt @param request Address of CeedRequest for non-blocking completion, else 15854cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1586cae8b89aSjeremylt 1587cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 1588cae8b89aSjeremylt 15897a982d89SJeremy L. Thompson @ref User 1590cae8b89aSjeremylt **/ 1591cae8b89aSjeremylt int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, 1592cae8b89aSjeremylt CeedRequest *request) { 1593cae8b89aSjeremylt int ierr; 1594cae8b89aSjeremylt Ceed ceed = op->ceed; 1595250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 1596cae8b89aSjeremylt 1597250756a7Sjeremylt if (op->numelements) { 1598250756a7Sjeremylt // Standard Operator 1599250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1600250756a7Sjeremylt } else if (op->composite) { 1601250756a7Sjeremylt // Composite Operator 1602250756a7Sjeremylt if (op->ApplyAddComposite) { 1603250756a7Sjeremylt ierr = op->ApplyAddComposite(op, in, out, request); CeedChk(ierr); 1604cae8b89aSjeremylt } else { 1605250756a7Sjeremylt CeedInt numsub; 1606250756a7Sjeremylt ierr = CeedOperatorGetNumSub(op, &numsub); CeedChk(ierr); 1607250756a7Sjeremylt CeedOperator *suboperators; 1608250756a7Sjeremylt ierr = CeedOperatorGetSubList(op, &suboperators); CeedChk(ierr); 1609250756a7Sjeremylt 1610250756a7Sjeremylt for (CeedInt i=0; i<numsub; i++) { 1611250756a7Sjeremylt ierr = CeedOperatorApplyAdd(suboperators[i], in, out, request); 1612cae8b89aSjeremylt CeedChk(ierr); 16131d7d2407SJeremy L Thompson } 1614250756a7Sjeremylt } 1615250756a7Sjeremylt } 1616250756a7Sjeremylt 1617d7b241e6Sjeremylt return 0; 1618d7b241e6Sjeremylt } 1619d7b241e6Sjeremylt 1620d7b241e6Sjeremylt /** 1621b11c1e72Sjeremylt @brief Destroy a CeedOperator 1622d7b241e6Sjeremylt 1623d7b241e6Sjeremylt @param op CeedOperator to destroy 1624b11c1e72Sjeremylt 1625b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1626dfdf5a53Sjeremylt 16277a982d89SJeremy L. Thompson @ref User 1628b11c1e72Sjeremylt **/ 1629d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 1630d7b241e6Sjeremylt int ierr; 1631d7b241e6Sjeremylt 1632d7b241e6Sjeremylt if (!*op || --(*op)->refcount > 0) return 0; 1633d7b241e6Sjeremylt if ((*op)->Destroy) { 1634d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 1635d7b241e6Sjeremylt } 1636fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 1637fe2413ffSjeremylt // Free fields 16381d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 163952d6035fSJeremy L Thompson if ((*op)->inputfields[i]) { 164015910d16Sjeremylt if ((*op)->inputfields[i]->Erestrict != CEED_ELEMRESTRICTION_NONE) { 164171352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->inputfields[i]->Erestrict); 164271352a93Sjeremylt CeedChk(ierr); 164315910d16Sjeremylt } 164471352a93Sjeremylt if ((*op)->inputfields[i]->basis != CEED_BASIS_COLLOCATED) { 164571352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->inputfields[i]->basis); CeedChk(ierr); 164671352a93Sjeremylt } 164771352a93Sjeremylt if ((*op)->inputfields[i]->vec != CEED_VECTOR_ACTIVE && 164871352a93Sjeremylt (*op)->inputfields[i]->vec != CEED_VECTOR_NONE ) { 164971352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->inputfields[i]->vec); CeedChk(ierr); 165071352a93Sjeremylt } 1651d99fa3c5SJeremy L Thompson ierr = CeedFree(&(*op)->inputfields[i]->fieldname); CeedChk(ierr); 1652fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields[i]); CeedChk(ierr); 1653fe2413ffSjeremylt } 16541d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 1655d0eb30a5Sjeremylt if ((*op)->outputfields[i]) { 165671352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->outputfields[i]->Erestrict); 165771352a93Sjeremylt CeedChk(ierr); 165871352a93Sjeremylt if ((*op)->outputfields[i]->basis != CEED_BASIS_COLLOCATED) { 165971352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->outputfields[i]->basis); CeedChk(ierr); 166071352a93Sjeremylt } 166171352a93Sjeremylt if ((*op)->outputfields[i]->vec != CEED_VECTOR_ACTIVE && 166271352a93Sjeremylt (*op)->outputfields[i]->vec != CEED_VECTOR_NONE ) { 166371352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->outputfields[i]->vec); CeedChk(ierr); 166471352a93Sjeremylt } 1665d99fa3c5SJeremy L Thompson ierr = CeedFree(&(*op)->outputfields[i]->fieldname); CeedChk(ierr); 1666fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields[i]); CeedChk(ierr); 1667fe2413ffSjeremylt } 166852d6035fSJeremy L Thompson // Destroy suboperators 16691d102b48SJeremy L Thompson for (int i=0; i<(*op)->numsub; i++) 167052d6035fSJeremy L Thompson if ((*op)->suboperators[i]) { 167152d6035fSJeremy L Thompson ierr = CeedOperatorDestroy(&(*op)->suboperators[i]); CeedChk(ierr); 167252d6035fSJeremy L Thompson } 1673d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 1674d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 1675d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 1676fe2413ffSjeremylt 16775107b09fSJeremy L Thompson // Destroy fallback 16785107b09fSJeremy L Thompson if ((*op)->opfallback) { 16795107b09fSJeremy L Thompson ierr = (*op)->qffallback->Destroy((*op)->qffallback); CeedChk(ierr); 16805107b09fSJeremy L Thompson ierr = CeedFree(&(*op)->qffallback); CeedChk(ierr); 16815107b09fSJeremy L Thompson ierr = (*op)->opfallback->Destroy((*op)->opfallback); CeedChk(ierr); 16825107b09fSJeremy L Thompson ierr = CeedFree(&(*op)->opfallback); CeedChk(ierr); 16835107b09fSJeremy L Thompson } 16845107b09fSJeremy L Thompson 1685fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields); CeedChk(ierr); 1686fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields); CeedChk(ierr); 168752d6035fSJeremy L Thompson ierr = CeedFree(&(*op)->suboperators); CeedChk(ierr); 1688d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 1689d7b241e6Sjeremylt return 0; 1690d7b241e6Sjeremylt } 1691d7b241e6Sjeremylt 1692d7b241e6Sjeremylt /// @} 1693