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 17d7b241e6Sjeremylt #include <ceed-impl.h> 18d863ab9bSjeremylt #include <ceed-backend.h> 19d7b241e6Sjeremylt #include <string.h> 203bd813ffSjeremylt #include <math.h> 21d7b241e6Sjeremylt 22dfdf5a53Sjeremylt /// @file 237a982d89SJeremy L. Thompson /// Implementation of CeedOperator interfaces 247a982d89SJeremy L. Thompson 257a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 267a982d89SJeremy L. Thompson /// CeedOperator Library Internal Functions 277a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 287a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorDeveloper 297a982d89SJeremy L. Thompson /// @{ 307a982d89SJeremy L. Thompson 317a982d89SJeremy L. Thompson /** 327a982d89SJeremy L. Thompson @brief Duplicate a CeedOperator with a reference Ceed to fallback for advanced 337a982d89SJeremy L. Thompson CeedOperator functionality 347a982d89SJeremy L. Thompson 357a982d89SJeremy L. Thompson @param op CeedOperator to create fallback for 367a982d89SJeremy L. Thompson 377a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 387a982d89SJeremy L. Thompson 397a982d89SJeremy L. Thompson @ref Developer 407a982d89SJeremy L. Thompson **/ 417a982d89SJeremy L. Thompson int CeedOperatorCreateFallback(CeedOperator op) { 427a982d89SJeremy L. Thompson int ierr; 437a982d89SJeremy L. Thompson 447a982d89SJeremy L. Thompson // Fallback Ceed 457a982d89SJeremy L. Thompson const char *resource, *fallbackresource; 467a982d89SJeremy L. Thompson ierr = CeedGetResource(op->ceed, &resource); CeedChk(ierr); 477a982d89SJeremy L. Thompson ierr = CeedGetOperatorFallbackResource(op->ceed, &fallbackresource); 487a982d89SJeremy L. Thompson CeedChk(ierr); 497a982d89SJeremy L. Thompson if (!strcmp(resource, fallbackresource)) 507a982d89SJeremy L. Thompson // LCOV_EXCL_START 517a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Backend %s cannot create an operator" 527a982d89SJeremy L. Thompson "fallback to resource %s", resource, fallbackresource); 537a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 547a982d89SJeremy L. Thompson 557a982d89SJeremy L. Thompson // Fallback Ceed 567a982d89SJeremy L. Thompson Ceed ceedref; 577a982d89SJeremy L. Thompson if (!op->ceed->opfallbackceed) { 587a982d89SJeremy L. Thompson ierr = CeedInit(fallbackresource, &ceedref); CeedChk(ierr); 597a982d89SJeremy L. Thompson ceedref->opfallbackparent = op->ceed; 607a982d89SJeremy L. Thompson op->ceed->opfallbackceed = ceedref; 617a982d89SJeremy L. Thompson } 627a982d89SJeremy L. Thompson ceedref = op->ceed->opfallbackceed; 637a982d89SJeremy L. Thompson 647a982d89SJeremy L. Thompson // Clone Op 657a982d89SJeremy L. Thompson CeedOperator opref; 667a982d89SJeremy L. Thompson ierr = CeedCalloc(1, &opref); CeedChk(ierr); 677a982d89SJeremy L. Thompson memcpy(opref, op, sizeof(*opref)); CeedChk(ierr); 687a982d89SJeremy L. Thompson opref->data = NULL; 697a982d89SJeremy L. Thompson opref->setupdone = 0; 707a982d89SJeremy L. Thompson opref->ceed = ceedref; 717a982d89SJeremy L. Thompson ierr = ceedref->OperatorCreate(opref); CeedChk(ierr); 727a982d89SJeremy L. Thompson op->opfallback = opref; 737a982d89SJeremy L. Thompson 747a982d89SJeremy L. Thompson // Clone QF 757a982d89SJeremy L. Thompson CeedQFunction qfref; 767a982d89SJeremy L. Thompson ierr = CeedCalloc(1, &qfref); CeedChk(ierr); 777a982d89SJeremy L. Thompson memcpy(qfref, (op->qf), sizeof(*qfref)); CeedChk(ierr); 787a982d89SJeremy L. Thompson qfref->data = NULL; 797a982d89SJeremy L. Thompson qfref->ceed = ceedref; 807a982d89SJeremy L. Thompson ierr = ceedref->QFunctionCreate(qfref); CeedChk(ierr); 817a982d89SJeremy L. Thompson opref->qf = qfref; 827a982d89SJeremy L. Thompson op->qffallback = qfref; 837a982d89SJeremy L. Thompson 847a982d89SJeremy L. Thompson return 0; 857a982d89SJeremy L. Thompson } 867a982d89SJeremy L. Thompson 877a982d89SJeremy L. Thompson /** 887a982d89SJeremy L. Thompson @brief Check if a CeedOperator is ready to be used. 897a982d89SJeremy L. Thompson 907a982d89SJeremy L. Thompson @param[in] ceed Ceed object for error handling 917a982d89SJeremy L. Thompson @param[in] op CeedOperator to check 927a982d89SJeremy L. Thompson 937a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 947a982d89SJeremy L. Thompson 957a982d89SJeremy L. Thompson @ref Developer 967a982d89SJeremy L. Thompson **/ 977a982d89SJeremy L. Thompson static int CeedOperatorCheckReady(Ceed ceed, CeedOperator op) { 987a982d89SJeremy L. Thompson CeedQFunction qf = op->qf; 997a982d89SJeremy L. Thompson 1007a982d89SJeremy L. Thompson if (op->composite) { 1017a982d89SJeremy L. Thompson if (!op->numsub) 1027a982d89SJeremy L. Thompson // LCOV_EXCL_START 1037a982d89SJeremy L. Thompson return CeedError(ceed, 1, "No suboperators set"); 1047a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 1057a982d89SJeremy L. Thompson } else { 1067a982d89SJeremy L. Thompson if (op->nfields == 0) 1077a982d89SJeremy L. Thompson // LCOV_EXCL_START 1087a982d89SJeremy L. Thompson return CeedError(ceed, 1, "No operator fields set"); 1097a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 1107a982d89SJeremy L. Thompson if (op->nfields < qf->numinputfields + qf->numoutputfields) 1117a982d89SJeremy L. Thompson // LCOV_EXCL_START 1127a982d89SJeremy L. Thompson return CeedError(ceed, 1, "Not all operator fields set"); 1137a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 1147a982d89SJeremy L. Thompson if (!op->hasrestriction) 1157a982d89SJeremy L. Thompson // LCOV_EXCL_START 1167a982d89SJeremy L. Thompson return CeedError(ceed, 1,"At least one restriction required"); 1177a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 1187a982d89SJeremy L. Thompson if (op->numqpoints == 0) 1197a982d89SJeremy L. Thompson // LCOV_EXCL_START 1207a982d89SJeremy L. Thompson return CeedError(ceed, 1,"At least one non-collocated basis required"); 1217a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 1227a982d89SJeremy L. Thompson } 1237a982d89SJeremy L. Thompson 1247a982d89SJeremy L. Thompson return 0; 1257a982d89SJeremy L. Thompson } 1267a982d89SJeremy L. Thompson 1277a982d89SJeremy L. Thompson /** 1287a982d89SJeremy L. Thompson @brief View a field of a CeedOperator 1297a982d89SJeremy L. Thompson 1307a982d89SJeremy L. Thompson @param[in] field Operator field to view 1314c4400c7SValeria Barra @param[in] qffield QFunction field (carries field name) 1327a982d89SJeremy L. Thompson @param[in] fieldnumber Number of field being viewed 1334c4400c7SValeria Barra @param[in] sub true indicates sub-operator, which increases indentation; false for top-level operator 1344c4400c7SValeria Barra @param[in] in true for an input field; false for output field 1357a982d89SJeremy L. Thompson @param[in] stream Stream to view to, e.g., stdout 1367a982d89SJeremy L. Thompson 1377a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1387a982d89SJeremy L. Thompson 1397a982d89SJeremy L. Thompson @ref Utility 1407a982d89SJeremy L. Thompson **/ 1417a982d89SJeremy L. Thompson static int CeedOperatorFieldView(CeedOperatorField field, 1427a982d89SJeremy L. Thompson CeedQFunctionField qffield, 1437a982d89SJeremy L. Thompson CeedInt fieldnumber, bool sub, bool in, 1447a982d89SJeremy L. Thompson FILE *stream) { 1457a982d89SJeremy L. Thompson const char *pre = sub ? " " : ""; 1467a982d89SJeremy L. Thompson const char *inout = in ? "Input" : "Output"; 1477a982d89SJeremy L. Thompson 1487a982d89SJeremy L. Thompson fprintf(stream, "%s %s Field [%d]:\n" 1497a982d89SJeremy L. Thompson "%s Name: \"%s\"\n", 1507a982d89SJeremy L. Thompson pre, inout, fieldnumber, pre, qffield->fieldname); 1517a982d89SJeremy L. Thompson 1527a982d89SJeremy L. Thompson if (field->basis == CEED_BASIS_COLLOCATED) 1537a982d89SJeremy L. Thompson fprintf(stream, "%s Collocated basis\n", pre); 1547a982d89SJeremy L. Thompson 1557a982d89SJeremy L. Thompson if (field->vec == CEED_VECTOR_ACTIVE) 1567a982d89SJeremy L. Thompson fprintf(stream, "%s Active vector\n", pre); 1577a982d89SJeremy L. Thompson else if (field->vec == CEED_VECTOR_NONE) 1587a982d89SJeremy L. Thompson fprintf(stream, "%s No vector\n", pre); 1597a982d89SJeremy L. Thompson 1607a982d89SJeremy L. Thompson return 0; 1617a982d89SJeremy L. Thompson } 1627a982d89SJeremy L. Thompson 1637a982d89SJeremy L. Thompson /** 1647a982d89SJeremy L. Thompson @brief View a single CeedOperator 1657a982d89SJeremy L. Thompson 1667a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 1677a982d89SJeremy L. Thompson @param[in] sub Boolean flag for sub-operator 1687a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 1697a982d89SJeremy L. Thompson 1707a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 1717a982d89SJeremy L. Thompson 1727a982d89SJeremy L. Thompson @ref Utility 1737a982d89SJeremy L. Thompson **/ 1747a982d89SJeremy L. Thompson int CeedOperatorSingleView(CeedOperator op, bool sub, FILE *stream) { 1757a982d89SJeremy L. Thompson int ierr; 1767a982d89SJeremy L. Thompson const char *pre = sub ? " " : ""; 1777a982d89SJeremy L. Thompson 1787a982d89SJeremy L. Thompson CeedInt totalfields; 1797a982d89SJeremy L. Thompson ierr = CeedOperatorGetNumArgs(op, &totalfields); CeedChk(ierr); 1807a982d89SJeremy L. Thompson 1817a982d89SJeremy L. Thompson fprintf(stream, "%s %d Field%s\n", pre, totalfields, totalfields>1 ? "s" : ""); 1827a982d89SJeremy L. Thompson 1837a982d89SJeremy L. Thompson fprintf(stream, "%s %d Input Field%s:\n", pre, op->qf->numinputfields, 1847a982d89SJeremy L. Thompson op->qf->numinputfields>1 ? "s" : ""); 1857a982d89SJeremy L. Thompson for (CeedInt i=0; i<op->qf->numinputfields; i++) { 1867a982d89SJeremy L. Thompson ierr = CeedOperatorFieldView(op->inputfields[i], op->qf->inputfields[i], 1877a982d89SJeremy L. Thompson i, sub, 1, stream); CeedChk(ierr); 1887a982d89SJeremy L. Thompson } 1897a982d89SJeremy L. Thompson 1907a982d89SJeremy L. Thompson fprintf(stream, "%s %d Output Field%s:\n", pre, op->qf->numoutputfields, 1917a982d89SJeremy L. Thompson op->qf->numoutputfields>1 ? "s" : ""); 1927a982d89SJeremy L. Thompson for (CeedInt i=0; i<op->qf->numoutputfields; i++) { 1937a982d89SJeremy L. Thompson ierr = CeedOperatorFieldView(op->outputfields[i], op->qf->inputfields[i], 1947a982d89SJeremy L. Thompson i, sub, 0, stream); CeedChk(ierr); 1957a982d89SJeremy L. Thompson } 1967a982d89SJeremy L. Thompson 1977a982d89SJeremy L. Thompson return 0; 1987a982d89SJeremy L. Thompson } 1997a982d89SJeremy L. Thompson 200d99fa3c5SJeremy L Thompson /** 201d99fa3c5SJeremy L Thompson @brief Find the active vector basis for a CeedOperator 202d99fa3c5SJeremy L Thompson 203d99fa3c5SJeremy L Thompson @param[in] op CeedOperator to find active basis for 204d99fa3c5SJeremy L Thompson @param[out] activeBasis Basis for active input vector 205d99fa3c5SJeremy L Thompson 206d99fa3c5SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 207d99fa3c5SJeremy L Thompson 208d99fa3c5SJeremy L Thompson @ ref Developer 209d99fa3c5SJeremy L Thompson **/ 210d99fa3c5SJeremy L Thompson static int CeedOperatorGetActiveBasis(CeedOperator op, 211d99fa3c5SJeremy L Thompson CeedBasis *activeBasis) { 212d99fa3c5SJeremy L Thompson *activeBasis = NULL; 213d99fa3c5SJeremy L Thompson for (int i = 0; i < op->qf->numinputfields; i++) 214d99fa3c5SJeremy L Thompson if (op->inputfields[i]->vec == CEED_VECTOR_ACTIVE) { 215d99fa3c5SJeremy L Thompson *activeBasis = op->inputfields[i]->basis; 216d99fa3c5SJeremy L Thompson break; 217d99fa3c5SJeremy L Thompson } 218d99fa3c5SJeremy L Thompson 219d99fa3c5SJeremy L Thompson if (!*activeBasis) { 220d99fa3c5SJeremy L Thompson // LCOV_EXCL_START 221d99fa3c5SJeremy L Thompson int ierr; 222d99fa3c5SJeremy L Thompson Ceed ceed; 223d99fa3c5SJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 224d99fa3c5SJeremy L Thompson return CeedError(ceed, 1, 225d99fa3c5SJeremy L Thompson "No active basis found for automatic multigrid setup"); 226d99fa3c5SJeremy L Thompson // LCOV_EXCL_STOP 227d99fa3c5SJeremy L Thompson } 228d99fa3c5SJeremy L Thompson return 0; 229d99fa3c5SJeremy L Thompson } 230d99fa3c5SJeremy L Thompson 231d99fa3c5SJeremy L Thompson 232d99fa3c5SJeremy L Thompson /** 233d99fa3c5SJeremy L Thompson @brief Common code for creating a multigrid coarse operator and level 234d99fa3c5SJeremy L Thompson transfer operators for a CeedOperator 235d99fa3c5SJeremy L Thompson 236d99fa3c5SJeremy L Thompson @param[in] opFine Fine grid operator 237d99fa3c5SJeremy L Thompson @param[in] PMultFine L-vector multiplicity in parallel gather/scatter 238d99fa3c5SJeremy L Thompson @param[in] rstrCoarse Coarse grid restriction 239d99fa3c5SJeremy L Thompson @param[in] basisCoarse Coarse grid active vector basis 240d99fa3c5SJeremy L Thompson @param[in] basisCtoF Basis for coarse to fine interpolation 241d99fa3c5SJeremy L Thompson @param[out] opCoarse Coarse grid operator 242d99fa3c5SJeremy L Thompson @param[out] opProlong Coarse to fine operator 243d99fa3c5SJeremy L Thompson @param[out] opRestrict Fine to coarse operator 244d99fa3c5SJeremy L Thompson 245d99fa3c5SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 246d99fa3c5SJeremy L Thompson 247d99fa3c5SJeremy L Thompson @ref Developer 248d99fa3c5SJeremy L Thompson **/ 249d99fa3c5SJeremy L Thompson static int CeedOperatorMultigridLevel_Core(CeedOperator opFine, 250d99fa3c5SJeremy L Thompson CeedVector PMultFine, CeedElemRestriction rstrCoarse, CeedBasis basisCoarse, 251d99fa3c5SJeremy L Thompson CeedBasis basisCtoF, CeedOperator *opCoarse, CeedOperator *opProlong, 252d99fa3c5SJeremy L Thompson CeedOperator *opRestrict) { 253d99fa3c5SJeremy L Thompson int ierr; 254d99fa3c5SJeremy L Thompson Ceed ceed; 255d99fa3c5SJeremy L Thompson ierr = CeedOperatorGetCeed(opFine, &ceed); CeedChk(ierr); 256d99fa3c5SJeremy L Thompson 257d99fa3c5SJeremy L Thompson // Check for composite operator 258d99fa3c5SJeremy L Thompson bool isComposite; 259d99fa3c5SJeremy L Thompson ierr = CeedOperatorIsComposite(opFine, &isComposite); CeedChk(ierr); 260d99fa3c5SJeremy L Thompson if (isComposite) 261d99fa3c5SJeremy L Thompson // LCOV_EXCL_START 262d99fa3c5SJeremy L Thompson return CeedError(ceed, 1, 263d99fa3c5SJeremy L Thompson "Automatic multigrid setup for composite operators not supported"); 264d99fa3c5SJeremy L Thompson // LCOV_EXCL_STOP 265d99fa3c5SJeremy L Thompson 266d99fa3c5SJeremy L Thompson // Coarse Grid 267d99fa3c5SJeremy L Thompson ierr = CeedOperatorCreate(ceed, opFine->qf, opFine->dqf, opFine->dqfT, 268d99fa3c5SJeremy L Thompson opCoarse); CeedChk(ierr); 269d99fa3c5SJeremy L Thompson CeedElemRestriction rstrFine = NULL; 270d99fa3c5SJeremy L Thompson // -- Clone input fields 271d99fa3c5SJeremy L Thompson for (int i = 0; i < opFine->qf->numinputfields; i++) { 272d99fa3c5SJeremy L Thompson if (opFine->inputfields[i]->vec == CEED_VECTOR_ACTIVE) { 273d99fa3c5SJeremy L Thompson rstrFine = opFine->inputfields[i]->Erestrict; 274d99fa3c5SJeremy L Thompson ierr = CeedOperatorSetField(*opCoarse, opFine->inputfields[i]->fieldname, 275d99fa3c5SJeremy L Thompson rstrCoarse, basisCoarse, CEED_VECTOR_ACTIVE); 276d99fa3c5SJeremy L Thompson CeedChk(ierr); 277d99fa3c5SJeremy L Thompson } else { 278d99fa3c5SJeremy L Thompson ierr = CeedOperatorSetField(*opCoarse, opFine->inputfields[i]->fieldname, 279d99fa3c5SJeremy L Thompson opFine->inputfields[i]->Erestrict, 280d99fa3c5SJeremy L Thompson opFine->inputfields[i]->basis, 281d99fa3c5SJeremy L Thompson opFine->inputfields[i]->vec); CeedChk(ierr); 282d99fa3c5SJeremy L Thompson } 283d99fa3c5SJeremy L Thompson } 284d99fa3c5SJeremy L Thompson // -- Clone output fields 285d99fa3c5SJeremy L Thompson for (int i = 0; i < opFine->qf->numoutputfields; i++) { 286d99fa3c5SJeremy L Thompson if (opFine->outputfields[i]->vec == CEED_VECTOR_ACTIVE) { 287d99fa3c5SJeremy L Thompson ierr = CeedOperatorSetField(*opCoarse, opFine->outputfields[i]->fieldname, 288d99fa3c5SJeremy L Thompson rstrCoarse, basisCoarse, CEED_VECTOR_ACTIVE); 289d99fa3c5SJeremy L Thompson CeedChk(ierr); 290d99fa3c5SJeremy L Thompson } else { 291d99fa3c5SJeremy L Thompson ierr = CeedOperatorSetField(*opCoarse, opFine->outputfields[i]->fieldname, 292d99fa3c5SJeremy L Thompson opFine->outputfields[i]->Erestrict, 293d99fa3c5SJeremy L Thompson opFine->outputfields[i]->basis, 294d99fa3c5SJeremy L Thompson opFine->outputfields[i]->vec); CeedChk(ierr); 295d99fa3c5SJeremy L Thompson } 296d99fa3c5SJeremy L Thompson } 297d99fa3c5SJeremy L Thompson 298d99fa3c5SJeremy L Thompson // Multiplicity vector 299d99fa3c5SJeremy L Thompson CeedVector multVec, multE; 300d99fa3c5SJeremy L Thompson ierr = CeedElemRestrictionCreateVector(rstrFine, &multVec, &multE); 301d99fa3c5SJeremy L Thompson CeedChk(ierr); 302d99fa3c5SJeremy L Thompson ierr = CeedVectorSetValue(multE, 0.0); CeedChk(ierr); 303d99fa3c5SJeremy L Thompson ierr = CeedElemRestrictionApply(rstrFine, CEED_NOTRANSPOSE, PMultFine, multE, 304d99fa3c5SJeremy L Thompson CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 305d99fa3c5SJeremy L Thompson ierr = CeedVectorSetValue(multVec, 0.0); CeedChk(ierr); 306d99fa3c5SJeremy L Thompson ierr = CeedElemRestrictionApply(rstrFine, CEED_TRANSPOSE, multE, multVec, 307d99fa3c5SJeremy L Thompson CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 308d99fa3c5SJeremy L Thompson ierr = CeedVectorDestroy(&multE); CeedChk(ierr); 309d99fa3c5SJeremy L Thompson ierr = CeedVectorReciprocal(multVec); CeedChk(ierr); 310d99fa3c5SJeremy L Thompson 311d99fa3c5SJeremy L Thompson // Restriction 312d99fa3c5SJeremy L Thompson CeedInt ncomp; 313d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumComponents(basisCoarse, &ncomp); CeedChk(ierr); 314d99fa3c5SJeremy L Thompson CeedQFunction qfRestrict; 315d99fa3c5SJeremy L Thompson ierr = CeedQFunctionCreateInteriorByName(ceed, "Scale", &qfRestrict); 316d99fa3c5SJeremy L Thompson CeedChk(ierr); 317*777ff853SJeremy L Thompson CeedInt *ncompRData; 318*777ff853SJeremy L Thompson ierr = CeedCalloc(1, &ncompRData); CeedChk(ierr); 319*777ff853SJeremy L Thompson ncompRData[0] = ncomp; 320*777ff853SJeremy L Thompson CeedQFunctionContext ctxR; 321*777ff853SJeremy L Thompson ierr = CeedQFunctionContextCreate(ceed, &ctxR); CeedChk(ierr); 322*777ff853SJeremy L Thompson ierr = CeedQFunctionContextSetData(ctxR, CEED_MEM_HOST, CEED_OWN_POINTER, 323*777ff853SJeremy L Thompson sizeof(*ncompRData), ncompRData); 324*777ff853SJeremy L Thompson CeedChk(ierr); 325*777ff853SJeremy L Thompson ierr = CeedQFunctionSetContext(qfRestrict, ctxR); CeedChk(ierr); 326*777ff853SJeremy L Thompson ierr = CeedQFunctionContextDestroy(&ctxR); CeedChk(ierr); 327d99fa3c5SJeremy L Thompson ierr = CeedQFunctionAddInput(qfRestrict, "input", ncomp, CEED_EVAL_NONE); 328d99fa3c5SJeremy L Thompson CeedChk(ierr); 329d99fa3c5SJeremy L Thompson ierr = CeedQFunctionAddInput(qfRestrict, "scale", ncomp, CEED_EVAL_NONE); 330d99fa3c5SJeremy L Thompson CeedChk(ierr); 331d99fa3c5SJeremy L Thompson ierr = CeedQFunctionAddOutput(qfRestrict, "output", ncomp, CEED_EVAL_INTERP); 332d99fa3c5SJeremy L Thompson CeedChk(ierr); 333d99fa3c5SJeremy L Thompson 334d99fa3c5SJeremy L Thompson ierr = CeedOperatorCreate(ceed, qfRestrict, CEED_QFUNCTION_NONE, 335d99fa3c5SJeremy L Thompson CEED_QFUNCTION_NONE, opRestrict); 336d99fa3c5SJeremy L Thompson CeedChk(ierr); 337d99fa3c5SJeremy L Thompson ierr = CeedOperatorSetField(*opRestrict, "input", rstrFine, 338d99fa3c5SJeremy L Thompson CEED_BASIS_COLLOCATED, CEED_VECTOR_ACTIVE); 339d99fa3c5SJeremy L Thompson CeedChk(ierr); 340d99fa3c5SJeremy L Thompson ierr = CeedOperatorSetField(*opRestrict, "scale", rstrFine, 341d99fa3c5SJeremy L Thompson CEED_BASIS_COLLOCATED, multVec); 342d99fa3c5SJeremy L Thompson CeedChk(ierr); 343d99fa3c5SJeremy L Thompson ierr = CeedOperatorSetField(*opRestrict, "output", rstrCoarse, basisCtoF, 344d99fa3c5SJeremy L Thompson CEED_VECTOR_ACTIVE); CeedChk(ierr); 345d99fa3c5SJeremy L Thompson 346d99fa3c5SJeremy L Thompson // Prolongation 347d99fa3c5SJeremy L Thompson CeedQFunction qfProlong; 348d99fa3c5SJeremy L Thompson ierr = CeedQFunctionCreateInteriorByName(ceed, "Scale", &qfProlong); 349d99fa3c5SJeremy L Thompson CeedChk(ierr); 350*777ff853SJeremy L Thompson CeedInt *ncompPData; 351*777ff853SJeremy L Thompson ierr = CeedCalloc(1, &ncompPData); CeedChk(ierr); 352*777ff853SJeremy L Thompson ncompPData[0] = ncomp; 353*777ff853SJeremy L Thompson CeedQFunctionContext ctxP; 354*777ff853SJeremy L Thompson ierr = CeedQFunctionContextCreate(ceed, &ctxP); CeedChk(ierr); 355*777ff853SJeremy L Thompson ierr = CeedQFunctionContextSetData(ctxP, CEED_MEM_HOST, CEED_OWN_POINTER, 356*777ff853SJeremy L Thompson sizeof(*ncompPData), ncompPData); 357*777ff853SJeremy L Thompson CeedChk(ierr); 358*777ff853SJeremy L Thompson ierr = CeedQFunctionSetContext(qfProlong, ctxP); CeedChk(ierr); 359*777ff853SJeremy L Thompson ierr = CeedQFunctionContextDestroy(&ctxP); CeedChk(ierr); 360d99fa3c5SJeremy L Thompson ierr = CeedQFunctionAddInput(qfProlong, "input", ncomp, CEED_EVAL_INTERP); 361d99fa3c5SJeremy L Thompson CeedChk(ierr); 362d99fa3c5SJeremy L Thompson ierr = CeedQFunctionAddInput(qfProlong, "scale", ncomp, CEED_EVAL_NONE); 363d99fa3c5SJeremy L Thompson CeedChk(ierr); 364d99fa3c5SJeremy L Thompson ierr = CeedQFunctionAddOutput(qfProlong, "output", ncomp, CEED_EVAL_NONE); 365d99fa3c5SJeremy L Thompson CeedChk(ierr); 366d99fa3c5SJeremy L Thompson 367d99fa3c5SJeremy L Thompson ierr = CeedOperatorCreate(ceed, qfProlong, CEED_QFUNCTION_NONE, 368d99fa3c5SJeremy L Thompson CEED_QFUNCTION_NONE, opProlong); 369d99fa3c5SJeremy L Thompson CeedChk(ierr); 370d99fa3c5SJeremy L Thompson ierr = CeedOperatorSetField(*opProlong, "input", rstrCoarse, basisCtoF, 371d99fa3c5SJeremy L Thompson CEED_VECTOR_ACTIVE); CeedChk(ierr); 372d99fa3c5SJeremy L Thompson ierr = CeedOperatorSetField(*opProlong, "scale", rstrFine, 373d99fa3c5SJeremy L Thompson CEED_BASIS_COLLOCATED, multVec); 374d99fa3c5SJeremy L Thompson CeedChk(ierr); 375d99fa3c5SJeremy L Thompson ierr = CeedOperatorSetField(*opProlong, "output", rstrFine, 376d99fa3c5SJeremy L Thompson CEED_BASIS_COLLOCATED, CEED_VECTOR_ACTIVE); 377d99fa3c5SJeremy L Thompson CeedChk(ierr); 378d99fa3c5SJeremy L Thompson 379d99fa3c5SJeremy L Thompson // Cleanup 380d99fa3c5SJeremy L Thompson ierr = CeedVectorDestroy(&multVec); CeedChk(ierr); 381d99fa3c5SJeremy L Thompson ierr = CeedBasisDestroy(&basisCtoF); CeedChk(ierr); 382d99fa3c5SJeremy L Thompson ierr = CeedQFunctionDestroy(&qfRestrict); CeedChk(ierr); 383d99fa3c5SJeremy L Thompson ierr = CeedQFunctionDestroy(&qfProlong); CeedChk(ierr); 384d99fa3c5SJeremy L Thompson 385d99fa3c5SJeremy L Thompson return 0; 386d99fa3c5SJeremy L Thompson } 387d99fa3c5SJeremy L Thompson 3887a982d89SJeremy L. Thompson /// @} 3897a982d89SJeremy L. Thompson 3907a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3917a982d89SJeremy L. Thompson /// CeedOperator Backend API 3927a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3937a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorBackend 3947a982d89SJeremy L. Thompson /// @{ 3957a982d89SJeremy L. Thompson 3967a982d89SJeremy L. Thompson /** 3977a982d89SJeremy L. Thompson @brief Get the Ceed associated with a CeedOperator 3987a982d89SJeremy L. Thompson 3997a982d89SJeremy L. Thompson @param op CeedOperator 4007a982d89SJeremy L. Thompson @param[out] ceed Variable to store Ceed 4017a982d89SJeremy L. Thompson 4027a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4037a982d89SJeremy L. Thompson 4047a982d89SJeremy L. Thompson @ref Backend 4057a982d89SJeremy L. Thompson **/ 4067a982d89SJeremy L. Thompson 4077a982d89SJeremy L. Thompson int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 4087a982d89SJeremy L. Thompson *ceed = op->ceed; 4097a982d89SJeremy L. Thompson return 0; 4107a982d89SJeremy L. Thompson } 4117a982d89SJeremy L. Thompson 4127a982d89SJeremy L. Thompson /** 4137a982d89SJeremy L. Thompson @brief Get the number of elements associated with a CeedOperator 4147a982d89SJeremy L. Thompson 4157a982d89SJeremy L. Thompson @param op CeedOperator 4167a982d89SJeremy L. Thompson @param[out] numelem Variable to store number of elements 4177a982d89SJeremy L. Thompson 4187a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4197a982d89SJeremy L. Thompson 4207a982d89SJeremy L. Thompson @ref Backend 4217a982d89SJeremy L. Thompson **/ 4227a982d89SJeremy L. Thompson 4237a982d89SJeremy L. Thompson int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) { 4247a982d89SJeremy L. Thompson if (op->composite) 4257a982d89SJeremy L. Thompson // LCOV_EXCL_START 4267a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 4277a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4287a982d89SJeremy L. Thompson 4297a982d89SJeremy L. Thompson *numelem = op->numelements; 4307a982d89SJeremy L. Thompson return 0; 4317a982d89SJeremy L. Thompson } 4327a982d89SJeremy L. Thompson 4337a982d89SJeremy L. Thompson /** 4347a982d89SJeremy L. Thompson @brief Get the number of quadrature points associated with a CeedOperator 4357a982d89SJeremy L. Thompson 4367a982d89SJeremy L. Thompson @param op CeedOperator 4377a982d89SJeremy L. Thompson @param[out] numqpts Variable to store vector number of quadrature points 4387a982d89SJeremy L. Thompson 4397a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4407a982d89SJeremy L. Thompson 4417a982d89SJeremy L. Thompson @ref Backend 4427a982d89SJeremy L. Thompson **/ 4437a982d89SJeremy L. Thompson 4447a982d89SJeremy L. Thompson int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) { 4457a982d89SJeremy L. Thompson if (op->composite) 4467a982d89SJeremy L. Thompson // LCOV_EXCL_START 4477a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 4487a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4497a982d89SJeremy L. Thompson 4507a982d89SJeremy L. Thompson *numqpts = op->numqpoints; 4517a982d89SJeremy L. Thompson return 0; 4527a982d89SJeremy L. Thompson } 4537a982d89SJeremy L. Thompson 4547a982d89SJeremy L. Thompson /** 4557a982d89SJeremy L. Thompson @brief Get the number of arguments associated with a CeedOperator 4567a982d89SJeremy L. Thompson 4577a982d89SJeremy L. Thompson @param op CeedOperator 4587a982d89SJeremy L. Thompson @param[out] numargs Variable to store vector number of arguments 4597a982d89SJeremy L. Thompson 4607a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4617a982d89SJeremy L. Thompson 4627a982d89SJeremy L. Thompson @ref Backend 4637a982d89SJeremy L. Thompson **/ 4647a982d89SJeremy L. Thompson 4657a982d89SJeremy L. Thompson int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) { 4667a982d89SJeremy L. Thompson if (op->composite) 4677a982d89SJeremy L. Thompson // LCOV_EXCL_START 4687a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Not defined for composite operators"); 4697a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4707a982d89SJeremy L. Thompson 4717a982d89SJeremy L. Thompson *numargs = op->nfields; 4727a982d89SJeremy L. Thompson return 0; 4737a982d89SJeremy L. Thompson } 4747a982d89SJeremy L. Thompson 4757a982d89SJeremy L. Thompson /** 4767a982d89SJeremy L. Thompson @brief Get the setup status of a CeedOperator 4777a982d89SJeremy L. Thompson 4787a982d89SJeremy L. Thompson @param op CeedOperator 479fd364f38SJeremy L Thompson @param[out] issetupdone Variable to store setup status 4807a982d89SJeremy L. Thompson 4817a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4827a982d89SJeremy L. Thompson 4837a982d89SJeremy L. Thompson @ref Backend 4847a982d89SJeremy L. Thompson **/ 4857a982d89SJeremy L. Thompson 486fd364f38SJeremy L Thompson int CeedOperatorIsSetupDone(CeedOperator op, bool *issetupdone) { 487fd364f38SJeremy L Thompson *issetupdone = op->setupdone; 4887a982d89SJeremy L. Thompson return 0; 4897a982d89SJeremy L. Thompson } 4907a982d89SJeremy L. Thompson 4917a982d89SJeremy L. Thompson /** 4927a982d89SJeremy L. Thompson @brief Get the QFunction associated with a CeedOperator 4937a982d89SJeremy L. Thompson 4947a982d89SJeremy L. Thompson @param op CeedOperator 4957a982d89SJeremy L. Thompson @param[out] qf Variable to store QFunction 4967a982d89SJeremy L. Thompson 4977a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4987a982d89SJeremy L. Thompson 4997a982d89SJeremy L. Thompson @ref Backend 5007a982d89SJeremy L. Thompson **/ 5017a982d89SJeremy L. Thompson 5027a982d89SJeremy L. Thompson int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 5037a982d89SJeremy L. Thompson if (op->composite) 5047a982d89SJeremy L. Thompson // LCOV_EXCL_START 5057a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 5067a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 5077a982d89SJeremy L. Thompson 5087a982d89SJeremy L. Thompson *qf = op->qf; 5097a982d89SJeremy L. Thompson return 0; 5107a982d89SJeremy L. Thompson } 5117a982d89SJeremy L. Thompson 5127a982d89SJeremy L. Thompson /** 513c04a41a7SJeremy L Thompson @brief Get a boolean value indicating if the CeedOperator is composite 514c04a41a7SJeremy L Thompson 515c04a41a7SJeremy L Thompson @param op CeedOperator 516fd364f38SJeremy L Thompson @param[out] iscomposite Variable to store composite status 517c04a41a7SJeremy L Thompson 518c04a41a7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 519c04a41a7SJeremy L Thompson 520c04a41a7SJeremy L Thompson @ref Backend 521c04a41a7SJeremy L Thompson **/ 522c04a41a7SJeremy L Thompson 523fd364f38SJeremy L Thompson int CeedOperatorIsComposite(CeedOperator op, bool *iscomposite) { 524fd364f38SJeremy L Thompson *iscomposite = op->composite; 525c04a41a7SJeremy L Thompson return 0; 526c04a41a7SJeremy L Thompson } 527c04a41a7SJeremy L Thompson 528c04a41a7SJeremy L Thompson /** 5297a982d89SJeremy L. Thompson @brief Get the number of suboperators associated with a CeedOperator 5307a982d89SJeremy L. Thompson 5317a982d89SJeremy L. Thompson @param op CeedOperator 5327a982d89SJeremy L. Thompson @param[out] numsub Variable to store number of suboperators 5337a982d89SJeremy L. Thompson 5347a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5357a982d89SJeremy L. Thompson 5367a982d89SJeremy L. Thompson @ref Backend 5377a982d89SJeremy L. Thompson **/ 5387a982d89SJeremy L. Thompson 5397a982d89SJeremy L. Thompson int CeedOperatorGetNumSub(CeedOperator op, CeedInt *numsub) { 5407a982d89SJeremy L. Thompson if (!op->composite) 5417a982d89SJeremy L. Thompson // LCOV_EXCL_START 5427a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 5437a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 5447a982d89SJeremy L. Thompson 5457a982d89SJeremy L. Thompson *numsub = op->numsub; 5467a982d89SJeremy L. Thompson return 0; 5477a982d89SJeremy L. Thompson } 5487a982d89SJeremy L. Thompson 5497a982d89SJeremy L. Thompson /** 5507a982d89SJeremy L. Thompson @brief Get the list of suboperators associated with a CeedOperator 5517a982d89SJeremy L. Thompson 5527a982d89SJeremy L. Thompson @param op CeedOperator 5537a982d89SJeremy L. Thompson @param[out] suboperators Variable to store list of suboperators 5547a982d89SJeremy L. Thompson 5557a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5567a982d89SJeremy L. Thompson 5577a982d89SJeremy L. Thompson @ref Backend 5587a982d89SJeremy L. Thompson **/ 5597a982d89SJeremy L. Thompson 5607a982d89SJeremy L. Thompson int CeedOperatorGetSubList(CeedOperator op, CeedOperator **suboperators) { 5617a982d89SJeremy L. Thompson if (!op->composite) 5627a982d89SJeremy L. Thompson // LCOV_EXCL_START 5637a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 5647a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 5657a982d89SJeremy L. Thompson 5667a982d89SJeremy L. Thompson *suboperators = op->suboperators; 5677a982d89SJeremy L. Thompson return 0; 5687a982d89SJeremy L. Thompson } 5697a982d89SJeremy L. Thompson 5707a982d89SJeremy L. Thompson /** 5717a982d89SJeremy L. Thompson @brief Get the backend data of a CeedOperator 5727a982d89SJeremy L. Thompson 5737a982d89SJeremy L. Thompson @param op CeedOperator 5747a982d89SJeremy L. Thompson @param[out] data Variable to store data 5757a982d89SJeremy L. Thompson 5767a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5777a982d89SJeremy L. Thompson 5787a982d89SJeremy L. Thompson @ref Backend 5797a982d89SJeremy L. Thompson **/ 5807a982d89SJeremy L. Thompson 581*777ff853SJeremy L Thompson int CeedOperatorGetData(CeedOperator op, void *data) { 582*777ff853SJeremy L Thompson *(void **)data = op->data; 5837a982d89SJeremy L. Thompson return 0; 5847a982d89SJeremy L. Thompson } 5857a982d89SJeremy L. Thompson 5867a982d89SJeremy L. Thompson /** 5877a982d89SJeremy L. Thompson @brief Set the backend data of a CeedOperator 5887a982d89SJeremy L. Thompson 5897a982d89SJeremy L. Thompson @param[out] op CeedOperator 5907a982d89SJeremy L. Thompson @param data Data to set 5917a982d89SJeremy L. Thompson 5927a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5937a982d89SJeremy L. Thompson 5947a982d89SJeremy L. Thompson @ref Backend 5957a982d89SJeremy L. Thompson **/ 5967a982d89SJeremy L. Thompson 597*777ff853SJeremy L Thompson int CeedOperatorSetData(CeedOperator op, void *data) { 598*777ff853SJeremy L Thompson op->data = data; 5997a982d89SJeremy L. Thompson return 0; 6007a982d89SJeremy L. Thompson } 6017a982d89SJeremy L. Thompson 6027a982d89SJeremy L. Thompson /** 6037a982d89SJeremy L. Thompson @brief Set the setup flag of a CeedOperator to True 6047a982d89SJeremy L. Thompson 6057a982d89SJeremy L. Thompson @param op CeedOperator 6067a982d89SJeremy L. Thompson 6077a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6087a982d89SJeremy L. Thompson 6097a982d89SJeremy L. Thompson @ref Backend 6107a982d89SJeremy L. Thompson **/ 6117a982d89SJeremy L. Thompson 6127a982d89SJeremy L. Thompson int CeedOperatorSetSetupDone(CeedOperator op) { 6137a982d89SJeremy L. Thompson op->setupdone = 1; 6147a982d89SJeremy L. Thompson return 0; 6157a982d89SJeremy L. Thompson } 6167a982d89SJeremy L. Thompson 6177a982d89SJeremy L. Thompson /** 6187a982d89SJeremy L. Thompson @brief Get the CeedOperatorFields of a CeedOperator 6197a982d89SJeremy L. Thompson 6207a982d89SJeremy L. Thompson @param op CeedOperator 6217a982d89SJeremy L. Thompson @param[out] inputfields Variable to store inputfields 6227a982d89SJeremy L. Thompson @param[out] outputfields Variable to store outputfields 6237a982d89SJeremy L. Thompson 6247a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6257a982d89SJeremy L. Thompson 6267a982d89SJeremy L. Thompson @ref Backend 6277a982d89SJeremy L. Thompson **/ 6287a982d89SJeremy L. Thompson 6297a982d89SJeremy L. Thompson int CeedOperatorGetFields(CeedOperator op, CeedOperatorField **inputfields, 6307a982d89SJeremy L. Thompson CeedOperatorField **outputfields) { 6317a982d89SJeremy L. Thompson if (op->composite) 6327a982d89SJeremy L. Thompson // LCOV_EXCL_START 6337a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 6347a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 6357a982d89SJeremy L. Thompson 6367a982d89SJeremy L. Thompson if (inputfields) *inputfields = op->inputfields; 6377a982d89SJeremy L. Thompson if (outputfields) *outputfields = op->outputfields; 6387a982d89SJeremy L. Thompson return 0; 6397a982d89SJeremy L. Thompson } 6407a982d89SJeremy L. Thompson 6417a982d89SJeremy L. Thompson /** 6427a982d89SJeremy L. Thompson @brief Get the CeedElemRestriction of a CeedOperatorField 6437a982d89SJeremy L. Thompson 6447a982d89SJeremy L. Thompson @param opfield CeedOperatorField 6457a982d89SJeremy L. Thompson @param[out] rstr Variable to store CeedElemRestriction 6467a982d89SJeremy L. Thompson 6477a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6487a982d89SJeremy L. Thompson 6497a982d89SJeremy L. Thompson @ref Backend 6507a982d89SJeremy L. Thompson **/ 6517a982d89SJeremy L. Thompson 6527a982d89SJeremy L. Thompson int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield, 6537a982d89SJeremy L. Thompson CeedElemRestriction *rstr) { 6547a982d89SJeremy L. Thompson *rstr = opfield->Erestrict; 6557a982d89SJeremy L. Thompson return 0; 6567a982d89SJeremy L. Thompson } 6577a982d89SJeremy L. Thompson 6587a982d89SJeremy L. Thompson /** 6597a982d89SJeremy L. Thompson @brief Get the CeedBasis of a CeedOperatorField 6607a982d89SJeremy L. Thompson 6617a982d89SJeremy L. Thompson @param opfield CeedOperatorField 6627a982d89SJeremy L. Thompson @param[out] basis Variable to store CeedBasis 6637a982d89SJeremy L. Thompson 6647a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6657a982d89SJeremy L. Thompson 6667a982d89SJeremy L. Thompson @ref Backend 6677a982d89SJeremy L. Thompson **/ 6687a982d89SJeremy L. Thompson 6697a982d89SJeremy L. Thompson int CeedOperatorFieldGetBasis(CeedOperatorField opfield, CeedBasis *basis) { 6707a982d89SJeremy L. Thompson *basis = opfield->basis; 6717a982d89SJeremy L. Thompson return 0; 6727a982d89SJeremy L. Thompson } 6737a982d89SJeremy L. Thompson 6747a982d89SJeremy L. Thompson /** 6757a982d89SJeremy L. Thompson @brief Get the CeedVector of a CeedOperatorField 6767a982d89SJeremy L. Thompson 6777a982d89SJeremy L. Thompson @param opfield CeedOperatorField 6787a982d89SJeremy L. Thompson @param[out] vec Variable to store CeedVector 6797a982d89SJeremy L. Thompson 6807a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6817a982d89SJeremy L. Thompson 6827a982d89SJeremy L. Thompson @ref Backend 6837a982d89SJeremy L. Thompson **/ 6847a982d89SJeremy L. Thompson 6857a982d89SJeremy L. Thompson int CeedOperatorFieldGetVector(CeedOperatorField opfield, CeedVector *vec) { 6867a982d89SJeremy L. Thompson *vec = opfield->vec; 6877a982d89SJeremy L. Thompson return 0; 6887a982d89SJeremy L. Thompson } 6897a982d89SJeremy L. Thompson 6907a982d89SJeremy L. Thompson /// @} 6917a982d89SJeremy L. Thompson 6927a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 6937a982d89SJeremy L. Thompson /// CeedOperator Public API 6947a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 6957a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorUser 696dfdf5a53Sjeremylt /// @{ 697d7b241e6Sjeremylt 698d7b241e6Sjeremylt /** 6990219ea01SJeremy L Thompson @brief Create a CeedOperator and associate a CeedQFunction. A CeedBasis and 7000219ea01SJeremy L Thompson CeedElemRestriction can be associated with CeedQFunction fields with 7010219ea01SJeremy L Thompson \ref CeedOperatorSetField. 702d7b241e6Sjeremylt 703b11c1e72Sjeremylt @param ceed A Ceed object where the CeedOperator will be created 704d7b241e6Sjeremylt @param qf QFunction defining the action of the operator at quadrature points 70534138859Sjeremylt @param dqf QFunction defining the action of the Jacobian of @a qf (or 7064cc79fe7SJed Brown @ref CEED_QFUNCTION_NONE) 707d7b241e6Sjeremylt @param dqfT QFunction defining the action of the transpose of the Jacobian 7084cc79fe7SJed Brown of @a qf (or @ref CEED_QFUNCTION_NONE) 709b11c1e72Sjeremylt @param[out] op Address of the variable where the newly created 710b11c1e72Sjeremylt CeedOperator will be stored 711b11c1e72Sjeremylt 712b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 713dfdf5a53Sjeremylt 7147a982d89SJeremy L. Thompson @ref User 715d7b241e6Sjeremylt */ 716d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, 717d7b241e6Sjeremylt CeedQFunction dqfT, CeedOperator *op) { 718d7b241e6Sjeremylt int ierr; 719d7b241e6Sjeremylt 7205fe0d4faSjeremylt if (!ceed->OperatorCreate) { 7215fe0d4faSjeremylt Ceed delegate; 722aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 7235fe0d4faSjeremylt 7245fe0d4faSjeremylt if (!delegate) 725c042f62fSJeremy L Thompson // LCOV_EXCL_START 7265fe0d4faSjeremylt return CeedError(ceed, 1, "Backend does not support OperatorCreate"); 727c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 7285fe0d4faSjeremylt 7295fe0d4faSjeremylt ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr); 7305fe0d4faSjeremylt return 0; 7315fe0d4faSjeremylt } 7325fe0d4faSjeremylt 733b3b7035fSJeremy L Thompson if (!qf || qf == CEED_QFUNCTION_NONE) 734b3b7035fSJeremy L Thompson // LCOV_EXCL_START 735b3b7035fSJeremy L Thompson return CeedError(ceed, 1, "Operator must have a valid QFunction."); 736b3b7035fSJeremy L Thompson // LCOV_EXCL_STOP 737d7b241e6Sjeremylt ierr = CeedCalloc(1, op); CeedChk(ierr); 738d7b241e6Sjeremylt (*op)->ceed = ceed; 739d7b241e6Sjeremylt ceed->refcount++; 740d7b241e6Sjeremylt (*op)->refcount = 1; 741d7b241e6Sjeremylt (*op)->qf = qf; 742d7b241e6Sjeremylt qf->refcount++; 743442e7f0bSjeremylt if (dqf && dqf != CEED_QFUNCTION_NONE) { 744d7b241e6Sjeremylt (*op)->dqf = dqf; 745442e7f0bSjeremylt dqf->refcount++; 746442e7f0bSjeremylt } 747442e7f0bSjeremylt if (dqfT && dqfT != CEED_QFUNCTION_NONE) { 748d7b241e6Sjeremylt (*op)->dqfT = dqfT; 749442e7f0bSjeremylt dqfT->refcount++; 750442e7f0bSjeremylt } 751fe2413ffSjeremylt ierr = CeedCalloc(16, &(*op)->inputfields); CeedChk(ierr); 752fe2413ffSjeremylt ierr = CeedCalloc(16, &(*op)->outputfields); CeedChk(ierr); 753d7b241e6Sjeremylt ierr = ceed->OperatorCreate(*op); CeedChk(ierr); 754d7b241e6Sjeremylt return 0; 755d7b241e6Sjeremylt } 756d7b241e6Sjeremylt 757d7b241e6Sjeremylt /** 75852d6035fSJeremy L Thompson @brief Create an operator that composes the action of several operators 75952d6035fSJeremy L Thompson 76052d6035fSJeremy L Thompson @param ceed A Ceed object where the CeedOperator will be created 76152d6035fSJeremy L Thompson @param[out] op Address of the variable where the newly created 76252d6035fSJeremy L Thompson Composite CeedOperator will be stored 76352d6035fSJeremy L Thompson 76452d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 76552d6035fSJeremy L Thompson 7667a982d89SJeremy L. Thompson @ref User 76752d6035fSJeremy L Thompson */ 76852d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) { 76952d6035fSJeremy L Thompson int ierr; 77052d6035fSJeremy L Thompson 77152d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 77252d6035fSJeremy L Thompson Ceed delegate; 773aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 77452d6035fSJeremy L Thompson 775250756a7Sjeremylt if (delegate) { 77652d6035fSJeremy L Thompson ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr); 77752d6035fSJeremy L Thompson return 0; 77852d6035fSJeremy L Thompson } 779250756a7Sjeremylt } 78052d6035fSJeremy L Thompson 78152d6035fSJeremy L Thompson ierr = CeedCalloc(1, op); CeedChk(ierr); 78252d6035fSJeremy L Thompson (*op)->ceed = ceed; 78352d6035fSJeremy L Thompson ceed->refcount++; 78452d6035fSJeremy L Thompson (*op)->composite = true; 78552d6035fSJeremy L Thompson ierr = CeedCalloc(16, &(*op)->suboperators); CeedChk(ierr); 786250756a7Sjeremylt 787250756a7Sjeremylt if (ceed->CompositeOperatorCreate) { 78852d6035fSJeremy L Thompson ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr); 789250756a7Sjeremylt } 79052d6035fSJeremy L Thompson return 0; 79152d6035fSJeremy L Thompson } 79252d6035fSJeremy L Thompson 79352d6035fSJeremy L Thompson /** 794b11c1e72Sjeremylt @brief Provide a field to a CeedOperator for use by its CeedQFunction 795d7b241e6Sjeremylt 796d7b241e6Sjeremylt This function is used to specify both active and passive fields to a 797d7b241e6Sjeremylt CeedOperator. For passive fields, a vector @arg v must be provided. Passive 798d7b241e6Sjeremylt fields can inputs or outputs (updated in-place when operator is applied). 799d7b241e6Sjeremylt 800d7b241e6Sjeremylt Active fields must be specified using this function, but their data (in a 801d7b241e6Sjeremylt CeedVector) is passed in CeedOperatorApply(). There can be at most one active 802d7b241e6Sjeremylt input and at most one active output. 803d7b241e6Sjeremylt 8048c91a0c9SJeremy L Thompson @param op CeedOperator on which to provide the field 8058795c945Sjeremylt @param fieldname Name of the field (to be matched with the name used by 8068795c945Sjeremylt CeedQFunction) 807b11c1e72Sjeremylt @param r CeedElemRestriction 8084cc79fe7SJed Brown @param b CeedBasis in which the field resides or @ref CEED_BASIS_COLLOCATED 809b11c1e72Sjeremylt if collocated with quadrature points 8104cc79fe7SJed Brown @param v CeedVector to be used by CeedOperator or @ref CEED_VECTOR_ACTIVE 8114cc79fe7SJed Brown if field is active or @ref CEED_VECTOR_NONE if using 8124cc79fe7SJed Brown @ref CEED_EVAL_WEIGHT in the QFunction 813b11c1e72Sjeremylt 814b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 815dfdf5a53Sjeremylt 8167a982d89SJeremy L. Thompson @ref User 817b11c1e72Sjeremylt **/ 818d7b241e6Sjeremylt int CeedOperatorSetField(CeedOperator op, const char *fieldname, 819a8d32208Sjeremylt CeedElemRestriction r, CeedBasis b, CeedVector v) { 820d7b241e6Sjeremylt int ierr; 82152d6035fSJeremy L Thompson if (op->composite) 822c042f62fSJeremy L Thompson // LCOV_EXCL_START 82352d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Cannot add field to composite operator."); 824c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 8258b067b84SJed Brown if (!r) 826c042f62fSJeremy L Thompson // LCOV_EXCL_START 827c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, 828c042f62fSJeremy L Thompson "ElemRestriction r for field \"%s\" must be non-NULL.", 829c042f62fSJeremy L Thompson fieldname); 830c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 8318b067b84SJed Brown if (!b) 832c042f62fSJeremy L Thompson // LCOV_EXCL_START 833c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Basis b for field \"%s\" must be non-NULL.", 834c042f62fSJeremy L Thompson fieldname); 835c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 8368b067b84SJed Brown if (!v) 837c042f62fSJeremy L Thompson // LCOV_EXCL_START 838c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Vector v for field \"%s\" must be non-NULL.", 839c042f62fSJeremy L Thompson fieldname); 840c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 84152d6035fSJeremy L Thompson 842d7b241e6Sjeremylt CeedInt numelements; 843d7b241e6Sjeremylt ierr = CeedElemRestrictionGetNumElements(r, &numelements); CeedChk(ierr); 84415910d16Sjeremylt if (r != CEED_ELEMRESTRICTION_NONE && op->hasrestriction && 84515910d16Sjeremylt op->numelements != numelements) 846c042f62fSJeremy L Thompson // LCOV_EXCL_START 847d7b241e6Sjeremylt return CeedError(op->ceed, 1, 8481d102b48SJeremy L Thompson "ElemRestriction with %d elements incompatible with prior " 8491d102b48SJeremy L Thompson "%d elements", numelements, op->numelements); 850c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 85115910d16Sjeremylt if (r != CEED_ELEMRESTRICTION_NONE) { 852d7b241e6Sjeremylt op->numelements = numelements; 8532cb0afc5Sjeremylt op->hasrestriction = true; // Restriction set, but numelements may be 0 85415910d16Sjeremylt } 855d7b241e6Sjeremylt 856783c99b3SValeria Barra if (b != CEED_BASIS_COLLOCATED) { 857d7b241e6Sjeremylt CeedInt numqpoints; 858d7b241e6Sjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &numqpoints); CeedChk(ierr); 859d7b241e6Sjeremylt if (op->numqpoints && op->numqpoints != numqpoints) 860c042f62fSJeremy L Thompson // LCOV_EXCL_START 8611d102b48SJeremy L Thompson return CeedError(op->ceed, 1, "Basis with %d quadrature points " 8621d102b48SJeremy L Thompson "incompatible with prior %d points", numqpoints, 8631d102b48SJeremy L Thompson op->numqpoints); 864c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 865d7b241e6Sjeremylt op->numqpoints = numqpoints; 866d7b241e6Sjeremylt } 86715910d16Sjeremylt CeedQFunctionField qfield; 868d1bcdac9Sjeremylt CeedOperatorField *ofield; 869d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numinputfields; i++) { 870fe2413ffSjeremylt if (!strcmp(fieldname, (*op->qf->inputfields[i]).fieldname)) { 87115910d16Sjeremylt qfield = op->qf->inputfields[i]; 872d7b241e6Sjeremylt ofield = &op->inputfields[i]; 873d7b241e6Sjeremylt goto found; 874d7b241e6Sjeremylt } 875d7b241e6Sjeremylt } 876d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numoutputfields; i++) { 877fe2413ffSjeremylt if (!strcmp(fieldname, (*op->qf->outputfields[i]).fieldname)) { 87815910d16Sjeremylt qfield = op->qf->inputfields[i]; 879d7b241e6Sjeremylt ofield = &op->outputfields[i]; 880d7b241e6Sjeremylt goto found; 881d7b241e6Sjeremylt } 882d7b241e6Sjeremylt } 883c042f62fSJeremy L Thompson // LCOV_EXCL_START 884d7b241e6Sjeremylt return CeedError(op->ceed, 1, "QFunction has no knowledge of field '%s'", 885d7b241e6Sjeremylt fieldname); 886c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 887d7b241e6Sjeremylt found: 88815910d16Sjeremylt if (r == CEED_ELEMRESTRICTION_NONE && qfield->emode != CEED_EVAL_WEIGHT) 889b0d62198Sjeremylt // LCOV_EXCL_START 89015910d16Sjeremylt return CeedError(op->ceed, 1, "CEED_ELEMRESTRICTION_NONE can only be used " 89115910d16Sjeremylt "for a field with eval mode CEED_EVAL_WEIGHT"); 892b0d62198Sjeremylt // LCOV_EXCL_STOP 893fe2413ffSjeremylt ierr = CeedCalloc(1, ofield); CeedChk(ierr); 894fe2413ffSjeremylt (*ofield)->Erestrict = r; 89571352a93Sjeremylt r->refcount += 1; 896fe2413ffSjeremylt (*ofield)->basis = b; 89771352a93Sjeremylt if (b != CEED_BASIS_COLLOCATED) 89871352a93Sjeremylt b->refcount += 1; 899fe2413ffSjeremylt (*ofield)->vec = v; 90071352a93Sjeremylt if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE) 90171352a93Sjeremylt v->refcount += 1; 902d7b241e6Sjeremylt op->nfields += 1; 903d99fa3c5SJeremy L Thompson 904d99fa3c5SJeremy L Thompson size_t len = strlen(fieldname); 905d99fa3c5SJeremy L Thompson char *tmp; 906d99fa3c5SJeremy L Thompson ierr = CeedCalloc(len+1, &tmp); CeedChk(ierr); 907d99fa3c5SJeremy L Thompson memcpy(tmp, fieldname, len+1); 908d99fa3c5SJeremy L Thompson (*ofield)->fieldname = tmp; 909d7b241e6Sjeremylt return 0; 910d7b241e6Sjeremylt } 911d7b241e6Sjeremylt 912d7b241e6Sjeremylt /** 91352d6035fSJeremy L Thompson @brief Add a sub-operator to a composite CeedOperator 914288c0443SJeremy L Thompson 91534138859Sjeremylt @param[out] compositeop Composite CeedOperator 91634138859Sjeremylt @param subop Sub-operator CeedOperator 91752d6035fSJeremy L Thompson 91852d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 91952d6035fSJeremy L Thompson 9207a982d89SJeremy L. Thompson @ref User 92152d6035fSJeremy L Thompson */ 922692c2638Sjeremylt int CeedCompositeOperatorAddSub(CeedOperator compositeop, CeedOperator subop) { 92352d6035fSJeremy L Thompson if (!compositeop->composite) 924c042f62fSJeremy L Thompson // LCOV_EXCL_START 9251d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "CeedOperator is not a composite " 9261d102b48SJeremy L Thompson "operator"); 927c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 92852d6035fSJeremy L Thompson 92952d6035fSJeremy L Thompson if (compositeop->numsub == CEED_COMPOSITE_MAX) 930c042f62fSJeremy L Thompson // LCOV_EXCL_START 9311d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "Cannot add additional suboperators"); 932c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 93352d6035fSJeremy L Thompson 93452d6035fSJeremy L Thompson compositeop->suboperators[compositeop->numsub] = subop; 93552d6035fSJeremy L Thompson subop->refcount++; 93652d6035fSJeremy L Thompson compositeop->numsub++; 93752d6035fSJeremy L Thompson return 0; 93852d6035fSJeremy L Thompson } 93952d6035fSJeremy L Thompson 94052d6035fSJeremy L Thompson /** 9411d102b48SJeremy L Thompson @brief Assemble a linear CeedQFunction associated with a CeedOperator 9421d102b48SJeremy L Thompson 9431d102b48SJeremy L Thompson This returns a CeedVector containing a matrix at each quadrature point 9441d102b48SJeremy L Thompson providing the action of the CeedQFunction associated with the CeedOperator. 9451d102b48SJeremy L Thompson The vector 'assembled' is of shape 9461d102b48SJeremy L Thompson [num_elements, num_input_fields, num_output_fields, num_quad_points] 9471d102b48SJeremy L Thompson and contains column-major matrices representing the action of the 9481d102b48SJeremy L Thompson CeedQFunction for a corresponding quadrature point on an element. Inputs and 9491d102b48SJeremy L Thompson outputs are in the order provided by the user when adding CeedOperator fields. 9504cc79fe7SJed Brown For example, a CeedQFunction with inputs 'u' and 'gradu' and outputs 'gradv' and 9511d102b48SJeremy L Thompson 'v', provided in that order, would result in an assembled QFunction that 9521d102b48SJeremy L Thompson consists of (1 + dim) x (dim + 1) matrices at each quadrature point acting 9531d102b48SJeremy L Thompson on the input [u, du_0, du_1] and producing the output [dv_0, dv_1, v]. 9541d102b48SJeremy L Thompson 9551d102b48SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 9561d102b48SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedQFunction at 9571d102b48SJeremy L Thompson quadrature points 9581d102b48SJeremy L Thompson @param[out] rstr CeedElemRestriction for CeedVector containing assembled 9591d102b48SJeremy L Thompson CeedQFunction 9601d102b48SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 9614cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 9621d102b48SJeremy L Thompson 9631d102b48SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 9641d102b48SJeremy L Thompson 9657a982d89SJeremy L. Thompson @ref User 9661d102b48SJeremy L Thompson **/ 96780ac2e43SJeremy L Thompson int CeedOperatorLinearAssembleQFunction(CeedOperator op, CeedVector *assembled, 9687f823360Sjeremylt CeedElemRestriction *rstr, 9697f823360Sjeremylt CeedRequest *request) { 9701d102b48SJeremy L Thompson int ierr; 9711d102b48SJeremy L Thompson Ceed ceed = op->ceed; 972250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 9731d102b48SJeremy L Thompson 9747172caadSjeremylt // Backend version 97580ac2e43SJeremy L Thompson if (op->LinearAssembleQFunction) { 97680ac2e43SJeremy L Thompson ierr = op->LinearAssembleQFunction(op, assembled, rstr, request); 9771d102b48SJeremy L Thompson CeedChk(ierr); 9785107b09fSJeremy L Thompson } else { 9795107b09fSJeremy L Thompson // Fallback to reference Ceed 9805107b09fSJeremy L Thompson if (!op->opfallback) { 9815107b09fSJeremy L Thompson ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 9825107b09fSJeremy L Thompson } 9835107b09fSJeremy L Thompson // Assemble 98480ac2e43SJeremy L Thompson ierr = op->opfallback->LinearAssembleQFunction(op->opfallback, assembled, 9855107b09fSJeremy L Thompson rstr, request); CeedChk(ierr); 9865107b09fSJeremy L Thompson } 987250756a7Sjeremylt 9881d102b48SJeremy L Thompson return 0; 9891d102b48SJeremy L Thompson } 9901d102b48SJeremy L Thompson 9911d102b48SJeremy L Thompson /** 992d965c7a7SJeremy L Thompson @brief Assemble the diagonal of a square linear CeedOperator 993b7ec98d8SJeremy L Thompson 9949e9210b8SJeremy L Thompson This overwrites a CeedVector with the diagonal of a linear CeedOperator. 995b7ec98d8SJeremy L Thompson 996c04a41a7SJeremy L Thompson Note: Currently only non-composite CeedOperators with a single field and 997c04a41a7SJeremy L Thompson composite CeedOperators with single field sub-operators are supported. 998d965c7a7SJeremy L Thompson 999b7ec98d8SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 1000b7ec98d8SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedOperator diagonal 1001b7ec98d8SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 10024cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1003b7ec98d8SJeremy L Thompson 1004b7ec98d8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1005b7ec98d8SJeremy L Thompson 10067a982d89SJeremy L. Thompson @ref User 1007b7ec98d8SJeremy L Thompson **/ 10082bba3ffaSJeremy L Thompson int CeedOperatorLinearAssembleDiagonal(CeedOperator op, CeedVector assembled, 10097f823360Sjeremylt CeedRequest *request) { 1010b7ec98d8SJeremy L Thompson int ierr; 1011b7ec98d8SJeremy L Thompson Ceed ceed = op->ceed; 1012250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 1013b7ec98d8SJeremy L Thompson 1014b7ec98d8SJeremy L Thompson // Use backend version, if available 101580ac2e43SJeremy L Thompson if (op->LinearAssembleDiagonal) { 101680ac2e43SJeremy L Thompson ierr = op->LinearAssembleDiagonal(op, assembled, request); CeedChk(ierr); 10179e9210b8SJeremy L Thompson } else if (op->LinearAssembleAddDiagonal) { 10189e9210b8SJeremy L Thompson ierr = CeedVectorSetValue(assembled, 0.0); CeedChk(ierr); 10199e9210b8SJeremy L Thompson return CeedOperatorLinearAssembleAddDiagonal(op, assembled, request); 10209e9210b8SJeremy L Thompson } else { 10219e9210b8SJeremy L Thompson // Fallback to reference Ceed 10229e9210b8SJeremy L Thompson if (!op->opfallback) { 10239e9210b8SJeremy L Thompson ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 10249e9210b8SJeremy L Thompson } 10259e9210b8SJeremy L Thompson // Assemble 10269e9210b8SJeremy L Thompson if (op->opfallback->LinearAssembleDiagonal) { 10279e9210b8SJeremy L Thompson ierr = op->opfallback->LinearAssembleDiagonal(op->opfallback, assembled, 10289e9210b8SJeremy L Thompson request); CeedChk(ierr); 10299e9210b8SJeremy L Thompson } else { 10309e9210b8SJeremy L Thompson ierr = CeedVectorSetValue(assembled, 0.0); CeedChk(ierr); 10319e9210b8SJeremy L Thompson return CeedOperatorLinearAssembleAddDiagonal(op, assembled, request); 10329e9210b8SJeremy L Thompson } 10339e9210b8SJeremy L Thompson } 10349e9210b8SJeremy L Thompson 10359e9210b8SJeremy L Thompson return 0; 10369e9210b8SJeremy L Thompson } 10379e9210b8SJeremy L Thompson 10389e9210b8SJeremy L Thompson /** 10399e9210b8SJeremy L Thompson @brief Assemble the diagonal of a square linear CeedOperator 10409e9210b8SJeremy L Thompson 10419e9210b8SJeremy L Thompson This sums into a CeedVector the diagonal of a linear CeedOperator. 10429e9210b8SJeremy L Thompson 10439e9210b8SJeremy L Thompson Note: Currently only non-composite CeedOperators with a single field and 10449e9210b8SJeremy L Thompson composite CeedOperators with single field sub-operators are supported. 10459e9210b8SJeremy L Thompson 10469e9210b8SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 10479e9210b8SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedOperator diagonal 10489e9210b8SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 10499e9210b8SJeremy L Thompson @ref CEED_REQUEST_IMMEDIATE 10509e9210b8SJeremy L Thompson 10519e9210b8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 10529e9210b8SJeremy L Thompson 10539e9210b8SJeremy L Thompson @ref User 10549e9210b8SJeremy L Thompson **/ 10559e9210b8SJeremy L Thompson int CeedOperatorLinearAssembleAddDiagonal(CeedOperator op, CeedVector assembled, 10569e9210b8SJeremy L Thompson CeedRequest *request) { 10579e9210b8SJeremy L Thompson int ierr; 10589e9210b8SJeremy L Thompson Ceed ceed = op->ceed; 10599e9210b8SJeremy L Thompson ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 10609e9210b8SJeremy L Thompson 10619e9210b8SJeremy L Thompson // Use backend version, if available 10629e9210b8SJeremy L Thompson if (op->LinearAssembleAddDiagonal) { 10639e9210b8SJeremy L Thompson ierr = op->LinearAssembleAddDiagonal(op, assembled, request); CeedChk(ierr); 10647172caadSjeremylt } else { 10657172caadSjeremylt // Fallback to reference Ceed 10667172caadSjeremylt if (!op->opfallback) { 10677172caadSjeremylt ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 1068b7ec98d8SJeremy L Thompson } 10697172caadSjeremylt // Assemble 10702bba3ffaSJeremy L Thompson ierr = CeedVectorSetValue(assembled, 0.0); CeedChk(ierr); 10719e9210b8SJeremy L Thompson ierr = op->opfallback->LinearAssembleAddDiagonal(op->opfallback, assembled, 10727172caadSjeremylt request); CeedChk(ierr); 1073b7ec98d8SJeremy L Thompson } 1074b7ec98d8SJeremy L Thompson 1075b7ec98d8SJeremy L Thompson return 0; 1076b7ec98d8SJeremy L Thompson } 1077b7ec98d8SJeremy L Thompson 1078b7ec98d8SJeremy L Thompson /** 1079d965c7a7SJeremy L Thompson @brief Assemble the point block diagonal of a square linear CeedOperator 1080d965c7a7SJeremy L Thompson 10819e9210b8SJeremy L Thompson This overwrites a CeedVector with the point block diagonal of a linear 1082d965c7a7SJeremy L Thompson CeedOperator. 1083d965c7a7SJeremy L Thompson 1084c04a41a7SJeremy L Thompson Note: Currently only non-composite CeedOperators with a single field and 1085c04a41a7SJeremy L Thompson composite CeedOperators with single field sub-operators are supported. 1086d965c7a7SJeremy L Thompson 1087d965c7a7SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 1088d965c7a7SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedOperator point block 1089d965c7a7SJeremy L Thompson diagonal, provided in row-major form with an 1090d965c7a7SJeremy L Thompson @a ncomp * @a ncomp block at each node. The dimensions 1091d965c7a7SJeremy L Thompson of this vector are derived from the active vector 1092d965c7a7SJeremy L Thompson for the CeedOperator. The array has shape 1093d965c7a7SJeremy L Thompson [nodes, component out, component in]. 1094d965c7a7SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 1095d965c7a7SJeremy L Thompson CEED_REQUEST_IMMEDIATE 1096d965c7a7SJeremy L Thompson 1097d965c7a7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1098d965c7a7SJeremy L Thompson 1099d965c7a7SJeremy L Thompson @ref User 1100d965c7a7SJeremy L Thompson **/ 110180ac2e43SJeremy L Thompson int CeedOperatorLinearAssemblePointBlockDiagonal(CeedOperator op, 11022bba3ffaSJeremy L Thompson CeedVector assembled, CeedRequest *request) { 1103d965c7a7SJeremy L Thompson int ierr; 1104d965c7a7SJeremy L Thompson Ceed ceed = op->ceed; 1105d965c7a7SJeremy L Thompson ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 1106d965c7a7SJeremy L Thompson 1107d965c7a7SJeremy L Thompson // Use backend version, if available 110880ac2e43SJeremy L Thompson if (op->LinearAssemblePointBlockDiagonal) { 110980ac2e43SJeremy L Thompson ierr = op->LinearAssemblePointBlockDiagonal(op, assembled, request); 1110d965c7a7SJeremy L Thompson CeedChk(ierr); 11119e9210b8SJeremy L Thompson } else if (op->LinearAssembleAddPointBlockDiagonal) { 11129e9210b8SJeremy L Thompson ierr = CeedVectorSetValue(assembled, 0.0); CeedChk(ierr); 11139e9210b8SJeremy L Thompson return CeedOperatorLinearAssembleAddPointBlockDiagonal(op, assembled, 11149e9210b8SJeremy L Thompson request); 1115d965c7a7SJeremy L Thompson } else { 1116d965c7a7SJeremy L Thompson // Fallback to reference Ceed 1117d965c7a7SJeremy L Thompson if (!op->opfallback) { 1118d965c7a7SJeremy L Thompson ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 1119d965c7a7SJeremy L Thompson } 1120d965c7a7SJeremy L Thompson // Assemble 11219e9210b8SJeremy L Thompson if (op->opfallback->LinearAssemblePointBlockDiagonal) { 112280ac2e43SJeremy L Thompson ierr = op->opfallback->LinearAssemblePointBlockDiagonal(op->opfallback, 1123d965c7a7SJeremy L Thompson assembled, request); CeedChk(ierr); 11249e9210b8SJeremy L Thompson } else { 11259e9210b8SJeremy L Thompson ierr = CeedVectorSetValue(assembled, 0.0); CeedChk(ierr); 11269e9210b8SJeremy L Thompson return CeedOperatorLinearAssembleAddPointBlockDiagonal(op, assembled, 11279e9210b8SJeremy L Thompson request); 11289e9210b8SJeremy L Thompson } 11299e9210b8SJeremy L Thompson } 11309e9210b8SJeremy L Thompson 11319e9210b8SJeremy L Thompson return 0; 11329e9210b8SJeremy L Thompson } 11339e9210b8SJeremy L Thompson 11349e9210b8SJeremy L Thompson /** 11359e9210b8SJeremy L Thompson @brief Assemble the point block diagonal of a square linear CeedOperator 11369e9210b8SJeremy L Thompson 11379e9210b8SJeremy L Thompson This sums into a CeedVector with the point block diagonal of a linear 11389e9210b8SJeremy L Thompson CeedOperator. 11399e9210b8SJeremy L Thompson 11409e9210b8SJeremy L Thompson Note: Currently only non-composite CeedOperators with a single field and 11419e9210b8SJeremy L Thompson composite CeedOperators with single field sub-operators are supported. 11429e9210b8SJeremy L Thompson 11439e9210b8SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 11449e9210b8SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedOperator point block 11459e9210b8SJeremy L Thompson diagonal, provided in row-major form with an 11469e9210b8SJeremy L Thompson @a ncomp * @a ncomp block at each node. The dimensions 11479e9210b8SJeremy L Thompson of this vector are derived from the active vector 11489e9210b8SJeremy L Thompson for the CeedOperator. The array has shape 11499e9210b8SJeremy L Thompson [nodes, component out, component in]. 11509e9210b8SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 11519e9210b8SJeremy L Thompson CEED_REQUEST_IMMEDIATE 11529e9210b8SJeremy L Thompson 11539e9210b8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 11549e9210b8SJeremy L Thompson 11559e9210b8SJeremy L Thompson @ref User 11569e9210b8SJeremy L Thompson **/ 11579e9210b8SJeremy L Thompson int CeedOperatorLinearAssembleAddPointBlockDiagonal(CeedOperator op, 11589e9210b8SJeremy L Thompson CeedVector assembled, CeedRequest *request) { 11599e9210b8SJeremy L Thompson int ierr; 11609e9210b8SJeremy L Thompson Ceed ceed = op->ceed; 11619e9210b8SJeremy L Thompson ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 11629e9210b8SJeremy L Thompson 11639e9210b8SJeremy L Thompson // Use backend version, if available 11649e9210b8SJeremy L Thompson if (op->LinearAssembleAddPointBlockDiagonal) { 11659e9210b8SJeremy L Thompson ierr = op->LinearAssembleAddPointBlockDiagonal(op, assembled, request); 11669e9210b8SJeremy L Thompson CeedChk(ierr); 11679e9210b8SJeremy L Thompson } else { 11689e9210b8SJeremy L Thompson // Fallback to reference Ceed 11699e9210b8SJeremy L Thompson if (!op->opfallback) { 11709e9210b8SJeremy L Thompson ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 11719e9210b8SJeremy L Thompson } 11729e9210b8SJeremy L Thompson // Assemble 11739e9210b8SJeremy L Thompson ierr = op->opfallback->LinearAssembleAddPointBlockDiagonal(op->opfallback, 11749e9210b8SJeremy L Thompson assembled, request); CeedChk(ierr); 1175d965c7a7SJeremy L Thompson } 1176d965c7a7SJeremy L Thompson 1177d965c7a7SJeremy L Thompson return 0; 1178d965c7a7SJeremy L Thompson } 1179d965c7a7SJeremy L Thompson 1180d965c7a7SJeremy L Thompson /** 1181d99fa3c5SJeremy L Thompson @brief Create a multigrid coarse operator and level transfer operators 1182d99fa3c5SJeremy L Thompson for a CeedOperator, creating the prolongation basis from the 1183d99fa3c5SJeremy L Thompson fine and coarse grid interpolation 1184d99fa3c5SJeremy L Thompson 1185d99fa3c5SJeremy L Thompson @param[in] opFine Fine grid operator 1186d99fa3c5SJeremy L Thompson @param[in] PMultFine L-vector multiplicity in parallel gather/scatter 1187d99fa3c5SJeremy L Thompson @param[in] rstrCoarse Coarse grid restriction 1188d99fa3c5SJeremy L Thompson @param[in] basisCoarse Coarse grid active vector basis 1189d99fa3c5SJeremy L Thompson @param[out] opCoarse Coarse grid operator 1190d99fa3c5SJeremy L Thompson @param[out] opProlong Coarse to fine operator 1191d99fa3c5SJeremy L Thompson @param[out] opRestrict Fine to coarse operator 1192d99fa3c5SJeremy L Thompson 1193d99fa3c5SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1194d99fa3c5SJeremy L Thompson 1195d99fa3c5SJeremy L Thompson @ref User 1196d99fa3c5SJeremy L Thompson **/ 1197d99fa3c5SJeremy L Thompson int CeedOperatorMultigridLevelCreate(CeedOperator opFine, CeedVector PMultFine, 1198d99fa3c5SJeremy L Thompson CeedElemRestriction rstrCoarse, CeedBasis basisCoarse, 1199d99fa3c5SJeremy L Thompson CeedOperator *opCoarse, CeedOperator *opProlong, CeedOperator *opRestrict) { 1200d99fa3c5SJeremy L Thompson int ierr; 1201d99fa3c5SJeremy L Thompson Ceed ceed; 1202d99fa3c5SJeremy L Thompson ierr = CeedOperatorGetCeed(opFine, &ceed); CeedChk(ierr); 1203d99fa3c5SJeremy L Thompson 1204d99fa3c5SJeremy L Thompson // Check for compatible quadrature spaces 1205d99fa3c5SJeremy L Thompson CeedBasis basisFine; 1206d99fa3c5SJeremy L Thompson ierr = CeedOperatorGetActiveBasis(opFine, &basisFine); CeedChk(ierr); 1207d99fa3c5SJeremy L Thompson CeedInt Qf, Qc; 1208d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumQuadraturePoints(basisFine, &Qf); CeedChk(ierr); 1209d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumQuadraturePoints(basisCoarse, &Qc); CeedChk(ierr); 1210d99fa3c5SJeremy L Thompson if (Qf != Qc) 1211d99fa3c5SJeremy L Thompson // LCOV_EXCL_START 1212d99fa3c5SJeremy L Thompson return CeedError(ceed, 1, "Bases must have compatible quadrature spaces"); 1213d99fa3c5SJeremy L Thompson // LCOV_EXCL_STOP 1214d99fa3c5SJeremy L Thompson 1215d99fa3c5SJeremy L Thompson // Coarse to fine basis 1216d99fa3c5SJeremy L Thompson CeedInt Pf, Pc, Q = Qf; 1217d99fa3c5SJeremy L Thompson bool isTensorF, isTensorC; 1218d99fa3c5SJeremy L Thompson ierr = CeedBasisIsTensor(basisFine, &isTensorF); CeedChk(ierr); 1219d99fa3c5SJeremy L Thompson ierr = CeedBasisIsTensor(basisCoarse, &isTensorC); CeedChk(ierr); 1220d99fa3c5SJeremy L Thompson CeedScalar *interpC, *interpF, *interpCtoF, *tau; 1221d99fa3c5SJeremy L Thompson if (isTensorF && isTensorC) { 1222d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumNodes1D(basisFine, &Pf); CeedChk(ierr); 1223d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumNodes1D(basisCoarse, &Pc); CeedChk(ierr); 1224d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumQuadraturePoints1D(basisCoarse, &Q); CeedChk(ierr); 1225d99fa3c5SJeremy L Thompson } else if (!isTensorF && !isTensorC) { 1226d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumNodes(basisFine, &Pf); CeedChk(ierr); 1227d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumNodes(basisCoarse, &Pc); CeedChk(ierr); 1228d99fa3c5SJeremy L Thompson } else { 1229d99fa3c5SJeremy L Thompson // LCOV_EXCL_START 1230d99fa3c5SJeremy L Thompson return CeedError(ceed, 1, "Bases must both be tensor or non-tensor"); 1231d99fa3c5SJeremy L Thompson // LCOV_EXCL_STOP 1232d99fa3c5SJeremy L Thompson } 1233d99fa3c5SJeremy L Thompson 1234d99fa3c5SJeremy L Thompson ierr = CeedMalloc(Q*Pf, &interpF); CeedChk(ierr); 1235d99fa3c5SJeremy L Thompson ierr = CeedMalloc(Q*Pc, &interpC); CeedChk(ierr); 1236d99fa3c5SJeremy L Thompson ierr = CeedCalloc(Pc*Pf, &interpCtoF); CeedChk(ierr); 1237d99fa3c5SJeremy L Thompson ierr = CeedMalloc(Q, &tau); CeedChk(ierr); 1238d99fa3c5SJeremy L Thompson if (isTensorF) { 1239d99fa3c5SJeremy L Thompson memcpy(interpF, basisFine->interp1d, Q*Pf*sizeof basisFine->interp1d[0]); 1240d99fa3c5SJeremy L Thompson memcpy(interpC, basisCoarse->interp1d, Q*Pc*sizeof basisCoarse->interp1d[0]); 1241d99fa3c5SJeremy L Thompson } else { 1242d99fa3c5SJeremy L Thompson memcpy(interpF, basisFine->interp, Q*Pf*sizeof basisFine->interp[0]); 1243d99fa3c5SJeremy L Thompson memcpy(interpC, basisCoarse->interp, Q*Pc*sizeof basisCoarse->interp[0]); 1244d99fa3c5SJeremy L Thompson } 1245d99fa3c5SJeremy L Thompson 1246d99fa3c5SJeremy L Thompson // -- QR Factorization, interpF = Q R 1247d99fa3c5SJeremy L Thompson ierr = CeedQRFactorization(ceed, interpF, tau, Q, Pf); CeedChk(ierr); 1248d99fa3c5SJeremy L Thompson 1249d99fa3c5SJeremy L Thompson // -- Apply Qtranspose, interpC = Qtranspose interpC 1250d99fa3c5SJeremy L Thompson CeedHouseholderApplyQ(interpC, interpF, tau, CEED_TRANSPOSE, 1251d99fa3c5SJeremy L Thompson Q, Pc, Pf, Pc, 1); 1252d99fa3c5SJeremy L Thompson 1253d99fa3c5SJeremy L Thompson // -- Apply Rinv, interpCtoF = Rinv interpC 1254d99fa3c5SJeremy L Thompson for (CeedInt j=0; j<Pc; j++) { // Column j 1255d99fa3c5SJeremy L Thompson interpCtoF[j+Pc*(Pf-1)] = interpC[j+Pc*(Pf-1)]/interpF[Pf*Pf-1]; 1256d99fa3c5SJeremy L Thompson for (CeedInt i=Pf-2; i>=0; i--) { // Row i 1257d99fa3c5SJeremy L Thompson interpCtoF[j+Pc*i] = interpC[j+Pc*i]; 1258d99fa3c5SJeremy L Thompson for (CeedInt k=i+1; k<Pf; k++) 1259d99fa3c5SJeremy L Thompson interpCtoF[j+Pc*i] -= interpF[k+Pf*i]*interpCtoF[j+Pc*k]; 1260d99fa3c5SJeremy L Thompson interpCtoF[j+Pc*i] /= interpF[i+Pf*i]; 1261d99fa3c5SJeremy L Thompson } 1262d99fa3c5SJeremy L Thompson } 1263d99fa3c5SJeremy L Thompson ierr = CeedFree(&tau); CeedChk(ierr); 1264d99fa3c5SJeremy L Thompson ierr = CeedFree(&interpC); CeedChk(ierr); 1265d99fa3c5SJeremy L Thompson ierr = CeedFree(&interpF); CeedChk(ierr); 1266d99fa3c5SJeremy L Thompson 1267d99fa3c5SJeremy L Thompson // Fallback to interpCtoF versions of code 1268d99fa3c5SJeremy L Thompson if (isTensorF) { 1269d99fa3c5SJeremy L Thompson ierr = CeedOperatorMultigridLevelCreateTensorH1(opFine, PMultFine, 1270d99fa3c5SJeremy L Thompson rstrCoarse, basisCoarse, interpCtoF, opCoarse, opProlong, opRestrict); 1271d99fa3c5SJeremy L Thompson CeedChk(ierr); 1272d99fa3c5SJeremy L Thompson } else { 1273d99fa3c5SJeremy L Thompson ierr = CeedOperatorMultigridLevelCreateH1(opFine, PMultFine, 1274d99fa3c5SJeremy L Thompson rstrCoarse, basisCoarse, interpCtoF, opCoarse, opProlong, opRestrict); 1275d99fa3c5SJeremy L Thompson CeedChk(ierr); 1276d99fa3c5SJeremy L Thompson } 1277d99fa3c5SJeremy L Thompson 1278d99fa3c5SJeremy L Thompson // Cleanup 1279d99fa3c5SJeremy L Thompson ierr = CeedFree(&interpCtoF); CeedChk(ierr); 1280d99fa3c5SJeremy L Thompson return 0; 1281d99fa3c5SJeremy L Thompson } 1282d99fa3c5SJeremy L Thompson 1283d99fa3c5SJeremy L Thompson /** 1284d99fa3c5SJeremy L Thompson @brief Create a multigrid coarse operator and level transfer operators 1285d99fa3c5SJeremy L Thompson for a CeedOperator with a tensor basis for the active basis 1286d99fa3c5SJeremy L Thompson 1287d99fa3c5SJeremy L Thompson @param[in] opFine Fine grid operator 1288d99fa3c5SJeremy L Thompson @param[in] PMultFine L-vector multiplicity in parallel gather/scatter 1289d99fa3c5SJeremy L Thompson @param[in] rstrCoarse Coarse grid restriction 1290d99fa3c5SJeremy L Thompson @param[in] basisCoarse Coarse grid active vector basis 1291d99fa3c5SJeremy L Thompson @param[in] interpCtoF Matrix for coarse to fine interpolation 1292d99fa3c5SJeremy L Thompson @param[out] opCoarse Coarse grid operator 1293d99fa3c5SJeremy L Thompson @param[out] opProlong Coarse to fine operator 1294d99fa3c5SJeremy L Thompson @param[out] opRestrict Fine to coarse operator 1295d99fa3c5SJeremy L Thompson 1296d99fa3c5SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1297d99fa3c5SJeremy L Thompson 1298d99fa3c5SJeremy L Thompson @ref User 1299d99fa3c5SJeremy L Thompson **/ 1300d99fa3c5SJeremy L Thompson int CeedOperatorMultigridLevelCreateTensorH1(CeedOperator opFine, 1301d99fa3c5SJeremy L Thompson CeedVector PMultFine, CeedElemRestriction rstrCoarse, CeedBasis basisCoarse, 1302d99fa3c5SJeremy L Thompson const CeedScalar *interpCtoF, CeedOperator *opCoarse, 1303d99fa3c5SJeremy L Thompson CeedOperator *opProlong, CeedOperator *opRestrict) { 1304d99fa3c5SJeremy L Thompson int ierr; 1305d99fa3c5SJeremy L Thompson Ceed ceed; 1306d99fa3c5SJeremy L Thompson ierr = CeedOperatorGetCeed(opFine, &ceed); CeedChk(ierr); 1307d99fa3c5SJeremy L Thompson 1308d99fa3c5SJeremy L Thompson // Check for compatible quadrature spaces 1309d99fa3c5SJeremy L Thompson CeedBasis basisFine; 1310d99fa3c5SJeremy L Thompson ierr = CeedOperatorGetActiveBasis(opFine, &basisFine); CeedChk(ierr); 1311d99fa3c5SJeremy L Thompson CeedInt Qf, Qc; 1312d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumQuadraturePoints(basisFine, &Qf); CeedChk(ierr); 1313d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumQuadraturePoints(basisCoarse, &Qc); CeedChk(ierr); 1314d99fa3c5SJeremy L Thompson if (Qf != Qc) 1315d99fa3c5SJeremy L Thompson // LCOV_EXCL_START 1316d99fa3c5SJeremy L Thompson return CeedError(ceed, 1, "Bases must have compatible quadrature spaces"); 1317d99fa3c5SJeremy L Thompson // LCOV_EXCL_STOP 1318d99fa3c5SJeremy L Thompson 1319d99fa3c5SJeremy L Thompson // Coarse to fine basis 1320d99fa3c5SJeremy L Thompson CeedInt dim, ncomp, nnodesCoarse, P1dFine, P1dCoarse; 1321d99fa3c5SJeremy L Thompson ierr = CeedBasisGetDimension(basisFine, &dim); CeedChk(ierr); 1322d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumComponents(basisFine, &ncomp); CeedChk(ierr); 1323d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumNodes1D(basisFine, &P1dFine); CeedChk(ierr); 1324d99fa3c5SJeremy L Thompson ierr = CeedElemRestrictionGetElementSize(rstrCoarse, &nnodesCoarse); 1325d99fa3c5SJeremy L Thompson CeedChk(ierr); 1326d99fa3c5SJeremy L Thompson P1dCoarse = dim == 1 ? nnodesCoarse : 1327d99fa3c5SJeremy L Thompson dim == 2 ? sqrt(nnodesCoarse) : 1328d99fa3c5SJeremy L Thompson cbrt(nnodesCoarse); 1329d99fa3c5SJeremy L Thompson CeedScalar *qref, *qweight, *grad; 1330d99fa3c5SJeremy L Thompson ierr = CeedCalloc(P1dFine, &qref); CeedChk(ierr); 1331d99fa3c5SJeremy L Thompson ierr = CeedCalloc(P1dFine, &qweight); CeedChk(ierr); 1332d99fa3c5SJeremy L Thompson ierr = CeedCalloc(P1dFine*P1dCoarse*dim, &grad); CeedChk(ierr); 1333d99fa3c5SJeremy L Thompson CeedBasis basisCtoF; 1334d99fa3c5SJeremy L Thompson ierr = CeedBasisCreateTensorH1(ceed, dim, ncomp, P1dCoarse, P1dFine, 1335d99fa3c5SJeremy L Thompson interpCtoF, grad, qref, qweight, &basisCtoF); 1336d99fa3c5SJeremy L Thompson CeedChk(ierr); 1337d99fa3c5SJeremy L Thompson ierr = CeedFree(&qref); CeedChk(ierr); 1338d99fa3c5SJeremy L Thompson ierr = CeedFree(&qweight); CeedChk(ierr); 1339d99fa3c5SJeremy L Thompson ierr = CeedFree(&grad); CeedChk(ierr); 1340d99fa3c5SJeremy L Thompson 1341d99fa3c5SJeremy L Thompson // Core code 1342d99fa3c5SJeremy L Thompson ierr = CeedOperatorMultigridLevel_Core(opFine, PMultFine, rstrCoarse, 1343d99fa3c5SJeremy L Thompson basisCoarse, basisCtoF, opCoarse, 1344d99fa3c5SJeremy L Thompson opProlong, opRestrict); 1345d99fa3c5SJeremy L Thompson CeedChk(ierr); 1346d99fa3c5SJeremy L Thompson return 0; 1347d99fa3c5SJeremy L Thompson } 1348d99fa3c5SJeremy L Thompson 1349d99fa3c5SJeremy L Thompson /** 1350d99fa3c5SJeremy L Thompson @brief Create a multigrid coarse operator and level transfer operators 1351d99fa3c5SJeremy L Thompson for a CeedOperator with a non-tensor basis for the active vector 1352d99fa3c5SJeremy L Thompson 1353d99fa3c5SJeremy L Thompson @param[in] opFine Fine grid operator 1354d99fa3c5SJeremy L Thompson @param[in] PMultFine L-vector multiplicity in parallel gather/scatter 1355d99fa3c5SJeremy L Thompson @param[in] rstrCoarse Coarse grid restriction 1356d99fa3c5SJeremy L Thompson @param[in] basisCoarse Coarse grid active vector basis 1357d99fa3c5SJeremy L Thompson @param[in] interpCtoF Matrix for coarse to fine interpolation 1358d99fa3c5SJeremy L Thompson @param[out] opCoarse Coarse grid operator 1359d99fa3c5SJeremy L Thompson @param[out] opProlong Coarse to fine operator 1360d99fa3c5SJeremy L Thompson @param[out] opRestrict Fine to coarse operator 1361d99fa3c5SJeremy L Thompson 1362d99fa3c5SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1363d99fa3c5SJeremy L Thompson 1364d99fa3c5SJeremy L Thompson @ref User 1365d99fa3c5SJeremy L Thompson **/ 1366d99fa3c5SJeremy L Thompson int CeedOperatorMultigridLevelCreateH1(CeedOperator opFine, 1367d99fa3c5SJeremy L Thompson CeedVector PMultFine, 1368d99fa3c5SJeremy L Thompson CeedElemRestriction rstrCoarse, 1369d99fa3c5SJeremy L Thompson CeedBasis basisCoarse, 1370d99fa3c5SJeremy L Thompson const CeedScalar *interpCtoF, 1371d99fa3c5SJeremy L Thompson CeedOperator *opCoarse, 1372d99fa3c5SJeremy L Thompson CeedOperator *opProlong, 1373d99fa3c5SJeremy L Thompson CeedOperator *opRestrict) { 1374d99fa3c5SJeremy L Thompson int ierr; 1375d99fa3c5SJeremy L Thompson Ceed ceed; 1376d99fa3c5SJeremy L Thompson ierr = CeedOperatorGetCeed(opFine, &ceed); CeedChk(ierr); 1377d99fa3c5SJeremy L Thompson 1378d99fa3c5SJeremy L Thompson // Check for compatible quadrature spaces 1379d99fa3c5SJeremy L Thompson CeedBasis basisFine; 1380d99fa3c5SJeremy L Thompson ierr = CeedOperatorGetActiveBasis(opFine, &basisFine); CeedChk(ierr); 1381d99fa3c5SJeremy L Thompson CeedInt Qf, Qc; 1382d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumQuadraturePoints(basisFine, &Qf); CeedChk(ierr); 1383d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumQuadraturePoints(basisCoarse, &Qc); CeedChk(ierr); 1384d99fa3c5SJeremy L Thompson if (Qf != Qc) 1385d99fa3c5SJeremy L Thompson // LCOV_EXCL_START 1386d99fa3c5SJeremy L Thompson return CeedError(ceed, 1, "Bases must have compatible quadrature spaces"); 1387d99fa3c5SJeremy L Thompson // LCOV_EXCL_STOP 1388d99fa3c5SJeremy L Thompson 1389d99fa3c5SJeremy L Thompson // Coarse to fine basis 1390d99fa3c5SJeremy L Thompson CeedElemTopology topo; 1391d99fa3c5SJeremy L Thompson ierr = CeedBasisGetTopology(basisFine, &topo); CeedChk(ierr); 1392d99fa3c5SJeremy L Thompson CeedInt dim, ncomp, nnodesCoarse, nnodesFine; 1393d99fa3c5SJeremy L Thompson ierr = CeedBasisGetDimension(basisFine, &dim); CeedChk(ierr); 1394d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumComponents(basisFine, &ncomp); CeedChk(ierr); 1395d99fa3c5SJeremy L Thompson ierr = CeedBasisGetNumNodes(basisFine, &nnodesFine); CeedChk(ierr); 1396d99fa3c5SJeremy L Thompson ierr = CeedElemRestrictionGetElementSize(rstrCoarse, &nnodesCoarse); 1397d99fa3c5SJeremy L Thompson CeedChk(ierr); 1398d99fa3c5SJeremy L Thompson CeedScalar *qref, *qweight, *grad; 1399d99fa3c5SJeremy L Thompson ierr = CeedCalloc(nnodesFine, &qref); CeedChk(ierr); 1400d99fa3c5SJeremy L Thompson ierr = CeedCalloc(nnodesFine, &qweight); CeedChk(ierr); 1401d99fa3c5SJeremy L Thompson ierr = CeedCalloc(nnodesFine*nnodesCoarse*dim, &grad); CeedChk(ierr); 1402d99fa3c5SJeremy L Thompson CeedBasis basisCtoF; 1403d99fa3c5SJeremy L Thompson ierr = CeedBasisCreateH1(ceed, topo, ncomp, nnodesCoarse, nnodesFine, 1404d99fa3c5SJeremy L Thompson interpCtoF, grad, qref, qweight, &basisCtoF); 1405d99fa3c5SJeremy L Thompson CeedChk(ierr); 1406d99fa3c5SJeremy L Thompson ierr = CeedFree(&qref); CeedChk(ierr); 1407d99fa3c5SJeremy L Thompson ierr = CeedFree(&qweight); CeedChk(ierr); 1408d99fa3c5SJeremy L Thompson ierr = CeedFree(&grad); CeedChk(ierr); 1409d99fa3c5SJeremy L Thompson 1410d99fa3c5SJeremy L Thompson // Core code 1411d99fa3c5SJeremy L Thompson ierr = CeedOperatorMultigridLevel_Core(opFine, PMultFine, rstrCoarse, 1412d99fa3c5SJeremy L Thompson basisCoarse, basisCtoF, opCoarse, 1413d99fa3c5SJeremy L Thompson opProlong, opRestrict); 1414d99fa3c5SJeremy L Thompson CeedChk(ierr); 1415d99fa3c5SJeremy L Thompson return 0; 1416d99fa3c5SJeremy L Thompson } 1417d99fa3c5SJeremy L Thompson 1418d99fa3c5SJeremy L Thompson /** 14193bd813ffSjeremylt @brief Build a FDM based approximate inverse for each element for a 14203bd813ffSjeremylt CeedOperator 14213bd813ffSjeremylt 14223bd813ffSjeremylt This returns a CeedOperator and CeedVector to apply a Fast Diagonalization 14233bd813ffSjeremylt Method based approximate inverse. This function obtains the simultaneous 14243bd813ffSjeremylt diagonalization for the 1D mass and Laplacian operators, 14253bd813ffSjeremylt M = V^T V, K = V^T S V. 14263bd813ffSjeremylt The assembled QFunction is used to modify the eigenvalues from simultaneous 14273bd813ffSjeremylt diagonalization and obtain an approximate inverse of the form 14283bd813ffSjeremylt V^T S^hat V. The CeedOperator must be linear and non-composite. The 14293bd813ffSjeremylt associated CeedQFunction must therefore also be linear. 14303bd813ffSjeremylt 14313bd813ffSjeremylt @param op CeedOperator to create element inverses 14323bd813ffSjeremylt @param[out] fdminv CeedOperator to apply the action of a FDM based inverse 14333bd813ffSjeremylt for each element 14343bd813ffSjeremylt @param request Address of CeedRequest for non-blocking completion, else 14354cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 14363bd813ffSjeremylt 14373bd813ffSjeremylt @return An error code: 0 - success, otherwise - failure 14383bd813ffSjeremylt 14397a982d89SJeremy L. Thompson @ref Backend 14403bd813ffSjeremylt **/ 14413bd813ffSjeremylt int CeedOperatorCreateFDMElementInverse(CeedOperator op, CeedOperator *fdminv, 14423bd813ffSjeremylt CeedRequest *request) { 14433bd813ffSjeremylt int ierr; 14443bd813ffSjeremylt Ceed ceed = op->ceed; 1445713f43c3Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 14463bd813ffSjeremylt 1447713f43c3Sjeremylt // Use backend version, if available 1448713f43c3Sjeremylt if (op->CreateFDMElementInverse) { 1449713f43c3Sjeremylt ierr = op->CreateFDMElementInverse(op, fdminv, request); CeedChk(ierr); 1450713f43c3Sjeremylt } else { 1451713f43c3Sjeremylt // Fallback to reference Ceed 1452713f43c3Sjeremylt if (!op->opfallback) { 1453713f43c3Sjeremylt ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 14543bd813ffSjeremylt } 1455713f43c3Sjeremylt // Assemble 1456713f43c3Sjeremylt ierr = op->opfallback->CreateFDMElementInverse(op->opfallback, fdminv, 14573bd813ffSjeremylt request); CeedChk(ierr); 14583bd813ffSjeremylt } 14593bd813ffSjeremylt 14603bd813ffSjeremylt return 0; 14613bd813ffSjeremylt } 14623bd813ffSjeremylt 14637a982d89SJeremy L. Thompson /** 14647a982d89SJeremy L. Thompson @brief View a CeedOperator 14657a982d89SJeremy L. Thompson 14667a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 14677a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 14687a982d89SJeremy L. Thompson 14697a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 14707a982d89SJeremy L. Thompson 14717a982d89SJeremy L. Thompson @ref User 14727a982d89SJeremy L. Thompson **/ 14737a982d89SJeremy L. Thompson int CeedOperatorView(CeedOperator op, FILE *stream) { 14747a982d89SJeremy L. Thompson int ierr; 14757a982d89SJeremy L. Thompson 14767a982d89SJeremy L. Thompson if (op->composite) { 14777a982d89SJeremy L. Thompson fprintf(stream, "Composite CeedOperator\n"); 14787a982d89SJeremy L. Thompson 14797a982d89SJeremy L. Thompson for (CeedInt i=0; i<op->numsub; i++) { 14807a982d89SJeremy L. Thompson fprintf(stream, " SubOperator [%d]:\n", i); 14817a982d89SJeremy L. Thompson ierr = CeedOperatorSingleView(op->suboperators[i], 1, stream); 14827a982d89SJeremy L. Thompson CeedChk(ierr); 14837a982d89SJeremy L. Thompson } 14847a982d89SJeremy L. Thompson } else { 14857a982d89SJeremy L. Thompson fprintf(stream, "CeedOperator\n"); 14867a982d89SJeremy L. Thompson ierr = CeedOperatorSingleView(op, 0, stream); CeedChk(ierr); 14877a982d89SJeremy L. Thompson } 14887a982d89SJeremy L. Thompson 14897a982d89SJeremy L. Thompson return 0; 14907a982d89SJeremy L. Thompson } 14913bd813ffSjeremylt 14923bd813ffSjeremylt /** 14933bd813ffSjeremylt @brief Apply CeedOperator to a vector 1494d7b241e6Sjeremylt 1495d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 1496d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 1497d7b241e6Sjeremylt CeedOperatorSetField(). 1498d7b241e6Sjeremylt 1499d7b241e6Sjeremylt @param op CeedOperator to apply 15004cc79fe7SJed Brown @param[in] in CeedVector containing input state or @ref CEED_VECTOR_NONE if 150134138859Sjeremylt there are no active inputs 1502b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 15034cc79fe7SJed Brown distinct from @a in) or @ref CEED_VECTOR_NONE if there are no 150434138859Sjeremylt active outputs 1505d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 15064cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1507b11c1e72Sjeremylt 1508b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1509dfdf5a53Sjeremylt 15107a982d89SJeremy L. Thompson @ref User 1511b11c1e72Sjeremylt **/ 1512692c2638Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, 1513692c2638Sjeremylt CeedRequest *request) { 1514d7b241e6Sjeremylt int ierr; 1515d7b241e6Sjeremylt Ceed ceed = op->ceed; 1516250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 1517d7b241e6Sjeremylt 1518250756a7Sjeremylt if (op->numelements) { 1519250756a7Sjeremylt // Standard Operator 1520cae8b89aSjeremylt if (op->Apply) { 1521250756a7Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 1522cae8b89aSjeremylt } else { 1523cae8b89aSjeremylt // Zero all output vectors 1524250756a7Sjeremylt CeedQFunction qf = op->qf; 1525cae8b89aSjeremylt for (CeedInt i=0; i<qf->numoutputfields; i++) { 1526cae8b89aSjeremylt CeedVector vec = op->outputfields[i]->vec; 1527cae8b89aSjeremylt if (vec == CEED_VECTOR_ACTIVE) 1528cae8b89aSjeremylt vec = out; 1529cae8b89aSjeremylt if (vec != CEED_VECTOR_NONE) { 1530cae8b89aSjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1531cae8b89aSjeremylt } 1532cae8b89aSjeremylt } 1533250756a7Sjeremylt // Apply 1534250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1535250756a7Sjeremylt } 1536250756a7Sjeremylt } else if (op->composite) { 1537250756a7Sjeremylt // Composite Operator 1538250756a7Sjeremylt if (op->ApplyComposite) { 1539250756a7Sjeremylt ierr = op->ApplyComposite(op, in, out, request); CeedChk(ierr); 1540250756a7Sjeremylt } else { 1541250756a7Sjeremylt CeedInt numsub; 1542250756a7Sjeremylt ierr = CeedOperatorGetNumSub(op, &numsub); CeedChk(ierr); 1543250756a7Sjeremylt CeedOperator *suboperators; 1544250756a7Sjeremylt ierr = CeedOperatorGetSubList(op, &suboperators); CeedChk(ierr); 1545250756a7Sjeremylt 1546250756a7Sjeremylt // Zero all output vectors 1547250756a7Sjeremylt if (out != CEED_VECTOR_NONE) { 1548cae8b89aSjeremylt ierr = CeedVectorSetValue(out, 0.0); CeedChk(ierr); 1549cae8b89aSjeremylt } 1550250756a7Sjeremylt for (CeedInt i=0; i<numsub; i++) { 1551250756a7Sjeremylt for (CeedInt j=0; j<suboperators[i]->qf->numoutputfields; j++) { 1552250756a7Sjeremylt CeedVector vec = suboperators[i]->outputfields[j]->vec; 1553250756a7Sjeremylt if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) { 1554250756a7Sjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1555250756a7Sjeremylt } 1556250756a7Sjeremylt } 1557250756a7Sjeremylt } 1558250756a7Sjeremylt // Apply 1559250756a7Sjeremylt for (CeedInt i=0; i<op->numsub; i++) { 1560250756a7Sjeremylt ierr = CeedOperatorApplyAdd(op->suboperators[i], in, out, request); 1561cae8b89aSjeremylt CeedChk(ierr); 1562cae8b89aSjeremylt } 1563cae8b89aSjeremylt } 1564250756a7Sjeremylt } 1565250756a7Sjeremylt 1566cae8b89aSjeremylt return 0; 1567cae8b89aSjeremylt } 1568cae8b89aSjeremylt 1569cae8b89aSjeremylt /** 1570cae8b89aSjeremylt @brief Apply CeedOperator to a vector and add result to output vector 1571cae8b89aSjeremylt 1572cae8b89aSjeremylt This computes the action of the operator on the specified (active) input, 1573cae8b89aSjeremylt yielding its (active) output. All inputs and outputs must be specified using 1574cae8b89aSjeremylt CeedOperatorSetField(). 1575cae8b89aSjeremylt 1576cae8b89aSjeremylt @param op CeedOperator to apply 1577cae8b89aSjeremylt @param[in] in CeedVector containing input state or NULL if there are no 1578cae8b89aSjeremylt active inputs 1579cae8b89aSjeremylt @param[out] out CeedVector to sum in result of applying operator (must be 1580cae8b89aSjeremylt distinct from @a in) or NULL if there are no active outputs 1581cae8b89aSjeremylt @param request Address of CeedRequest for non-blocking completion, else 15824cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1583cae8b89aSjeremylt 1584cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 1585cae8b89aSjeremylt 15867a982d89SJeremy L. Thompson @ref User 1587cae8b89aSjeremylt **/ 1588cae8b89aSjeremylt int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, 1589cae8b89aSjeremylt CeedRequest *request) { 1590cae8b89aSjeremylt int ierr; 1591cae8b89aSjeremylt Ceed ceed = op->ceed; 1592250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 1593cae8b89aSjeremylt 1594250756a7Sjeremylt if (op->numelements) { 1595250756a7Sjeremylt // Standard Operator 1596250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1597250756a7Sjeremylt } else if (op->composite) { 1598250756a7Sjeremylt // Composite Operator 1599250756a7Sjeremylt if (op->ApplyAddComposite) { 1600250756a7Sjeremylt ierr = op->ApplyAddComposite(op, in, out, request); CeedChk(ierr); 1601cae8b89aSjeremylt } else { 1602250756a7Sjeremylt CeedInt numsub; 1603250756a7Sjeremylt ierr = CeedOperatorGetNumSub(op, &numsub); CeedChk(ierr); 1604250756a7Sjeremylt CeedOperator *suboperators; 1605250756a7Sjeremylt ierr = CeedOperatorGetSubList(op, &suboperators); CeedChk(ierr); 1606250756a7Sjeremylt 1607250756a7Sjeremylt for (CeedInt i=0; i<numsub; i++) { 1608250756a7Sjeremylt ierr = CeedOperatorApplyAdd(suboperators[i], in, out, request); 1609cae8b89aSjeremylt CeedChk(ierr); 16101d7d2407SJeremy L Thompson } 1611250756a7Sjeremylt } 1612250756a7Sjeremylt } 1613250756a7Sjeremylt 1614d7b241e6Sjeremylt return 0; 1615d7b241e6Sjeremylt } 1616d7b241e6Sjeremylt 1617d7b241e6Sjeremylt /** 1618b11c1e72Sjeremylt @brief Destroy a CeedOperator 1619d7b241e6Sjeremylt 1620d7b241e6Sjeremylt @param op CeedOperator to destroy 1621b11c1e72Sjeremylt 1622b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1623dfdf5a53Sjeremylt 16247a982d89SJeremy L. Thompson @ref User 1625b11c1e72Sjeremylt **/ 1626d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 1627d7b241e6Sjeremylt int ierr; 1628d7b241e6Sjeremylt 1629d7b241e6Sjeremylt if (!*op || --(*op)->refcount > 0) return 0; 1630d7b241e6Sjeremylt if ((*op)->Destroy) { 1631d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 1632d7b241e6Sjeremylt } 1633fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 1634fe2413ffSjeremylt // Free fields 16351d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 163652d6035fSJeremy L Thompson if ((*op)->inputfields[i]) { 163715910d16Sjeremylt if ((*op)->inputfields[i]->Erestrict != CEED_ELEMRESTRICTION_NONE) { 163871352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->inputfields[i]->Erestrict); 163971352a93Sjeremylt CeedChk(ierr); 164015910d16Sjeremylt } 164171352a93Sjeremylt if ((*op)->inputfields[i]->basis != CEED_BASIS_COLLOCATED) { 164271352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->inputfields[i]->basis); CeedChk(ierr); 164371352a93Sjeremylt } 164471352a93Sjeremylt if ((*op)->inputfields[i]->vec != CEED_VECTOR_ACTIVE && 164571352a93Sjeremylt (*op)->inputfields[i]->vec != CEED_VECTOR_NONE ) { 164671352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->inputfields[i]->vec); CeedChk(ierr); 164771352a93Sjeremylt } 1648d99fa3c5SJeremy L Thompson ierr = CeedFree(&(*op)->inputfields[i]->fieldname); CeedChk(ierr); 1649fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields[i]); CeedChk(ierr); 1650fe2413ffSjeremylt } 16511d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 1652d0eb30a5Sjeremylt if ((*op)->outputfields[i]) { 165371352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->outputfields[i]->Erestrict); 165471352a93Sjeremylt CeedChk(ierr); 165571352a93Sjeremylt if ((*op)->outputfields[i]->basis != CEED_BASIS_COLLOCATED) { 165671352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->outputfields[i]->basis); CeedChk(ierr); 165771352a93Sjeremylt } 165871352a93Sjeremylt if ((*op)->outputfields[i]->vec != CEED_VECTOR_ACTIVE && 165971352a93Sjeremylt (*op)->outputfields[i]->vec != CEED_VECTOR_NONE ) { 166071352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->outputfields[i]->vec); CeedChk(ierr); 166171352a93Sjeremylt } 1662d99fa3c5SJeremy L Thompson ierr = CeedFree(&(*op)->outputfields[i]->fieldname); CeedChk(ierr); 1663fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields[i]); CeedChk(ierr); 1664fe2413ffSjeremylt } 166552d6035fSJeremy L Thompson // Destroy suboperators 16661d102b48SJeremy L Thompson for (int i=0; i<(*op)->numsub; i++) 166752d6035fSJeremy L Thompson if ((*op)->suboperators[i]) { 166852d6035fSJeremy L Thompson ierr = CeedOperatorDestroy(&(*op)->suboperators[i]); CeedChk(ierr); 166952d6035fSJeremy L Thompson } 1670d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 1671d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 1672d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 1673fe2413ffSjeremylt 16745107b09fSJeremy L Thompson // Destroy fallback 16755107b09fSJeremy L Thompson if ((*op)->opfallback) { 16765107b09fSJeremy L Thompson ierr = (*op)->qffallback->Destroy((*op)->qffallback); CeedChk(ierr); 16775107b09fSJeremy L Thompson ierr = CeedFree(&(*op)->qffallback); CeedChk(ierr); 16785107b09fSJeremy L Thompson ierr = (*op)->opfallback->Destroy((*op)->opfallback); CeedChk(ierr); 16795107b09fSJeremy L Thompson ierr = CeedFree(&(*op)->opfallback); CeedChk(ierr); 16805107b09fSJeremy L Thompson } 16815107b09fSJeremy L Thompson 1682fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields); CeedChk(ierr); 1683fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields); CeedChk(ierr); 168452d6035fSJeremy L Thompson ierr = CeedFree(&(*op)->suboperators); CeedChk(ierr); 1685d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 1686d7b241e6Sjeremylt return 0; 1687d7b241e6Sjeremylt } 1688d7b241e6Sjeremylt 1689d7b241e6Sjeremylt /// @} 1690