1f918ec44SMatthew G. Knepley #include <petsc/private/dmimpl.h> /*I "petscdm.h" I*/ 2d2b2dc1eSMatthew G. Knepley #include <petscdmceed.h> 3f918ec44SMatthew G. Knepley 4f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 5d2b2dc1eSMatthew G. Knepley #include <petsc/private/dmpleximpl.h> 6d2b2dc1eSMatthew G. Knepley #include <petscdmplexceed.h> 7d2b2dc1eSMatthew G. Knepley #include <petscfeceed.h> 8f918ec44SMatthew G. Knepley 9f918ec44SMatthew G. Knepley /*@C 1020f4b53cSBarry Smith DMGetCeed - Get the LibCEED context associated with this `DM` 11f918ec44SMatthew G. Knepley 1220f4b53cSBarry Smith Not Collective 13f918ec44SMatthew G. Knepley 14f918ec44SMatthew G. Knepley Input Parameter: 1520f4b53cSBarry Smith . DM - The `DM` 16f918ec44SMatthew G. Knepley 17f918ec44SMatthew G. Knepley Output Parameter: 18f918ec44SMatthew G. Knepley . ceed - The LibCEED context 19f918ec44SMatthew G. Knepley 20f918ec44SMatthew G. Knepley Level: intermediate 21f918ec44SMatthew G. Knepley 2220f4b53cSBarry Smith .seealso: `DM`, `DMCreate()` 23f918ec44SMatthew G. Knepley @*/ 24d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCeed(DM dm, Ceed *ceed) 25d71ae5a4SJacob Faibussowitsch { 26f918ec44SMatthew G. Knepley PetscFunctionBegin; 27f918ec44SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 284f572ea9SToby Isaac PetscAssertPointer(ceed, 2); 29f918ec44SMatthew G. Knepley if (!dm->ceed) { 30f918ec44SMatthew G. Knepley char ceedresource[PETSC_MAX_PATH_LEN]; /* libCEED resource specifier */ 31f918ec44SMatthew G. Knepley const char *prefix; 32f918ec44SMatthew G. Knepley 33c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(ceedresource, "/cpu/self", sizeof(ceedresource))); 349566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)dm, &prefix)); 359566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetString(NULL, prefix, "-dm_ceed", ceedresource, sizeof(ceedresource), NULL)); 369566063dSJacob Faibussowitsch PetscCallCEED(CeedInit(ceedresource, &dm->ceed)); 37f918ec44SMatthew G. Knepley } 38f918ec44SMatthew G. Knepley *ceed = dm->ceed; 393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40f918ec44SMatthew G. Knepley } 41f918ec44SMatthew G. Knepley 42d2b2dc1eSMatthew G. Knepley static CeedMemType PetscMemType2Ceed(PetscMemType mem_type) 43d2b2dc1eSMatthew G. Knepley { 447ce467fcSMatthew G. Knepley return PetscMemTypeDevice(mem_type) ? CEED_MEM_DEVICE : CEED_MEM_HOST; 457ce467fcSMatthew G. Knepley } 467ce467fcSMatthew G. Knepley 477ce467fcSMatthew G. Knepley PetscErrorCode VecGetCeedVector(Vec X, Ceed ceed, CeedVector *cx) 487ce467fcSMatthew G. Knepley { 497ce467fcSMatthew G. Knepley PetscMemType memtype; 507ce467fcSMatthew G. Knepley PetscScalar *x; 517ce467fcSMatthew G. Knepley PetscInt n; 527ce467fcSMatthew G. Knepley 537ce467fcSMatthew G. Knepley PetscFunctionBegin; 547ce467fcSMatthew G. Knepley PetscCall(VecGetLocalSize(X, &n)); 557ce467fcSMatthew G. Knepley PetscCall(VecGetArrayAndMemType(X, &x, &memtype)); 567ce467fcSMatthew G. Knepley PetscCallCEED(CeedVectorCreate(ceed, n, cx)); 577ce467fcSMatthew G. Knepley PetscCallCEED(CeedVectorSetArray(*cx, PetscMemType2Ceed(memtype), CEED_USE_POINTER, x)); 58d2b2dc1eSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 597ce467fcSMatthew G. Knepley } 607ce467fcSMatthew G. Knepley 617ce467fcSMatthew G. Knepley PetscErrorCode VecRestoreCeedVector(Vec X, CeedVector *cx) 627ce467fcSMatthew G. Knepley { 637ce467fcSMatthew G. Knepley PetscFunctionBegin; 647ce467fcSMatthew G. Knepley PetscCall(VecRestoreArrayAndMemType(X, NULL)); 657ce467fcSMatthew G. Knepley PetscCallCEED(CeedVectorDestroy(cx)); 66d2b2dc1eSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 677ce467fcSMatthew G. Knepley } 687ce467fcSMatthew G. Knepley 697ce467fcSMatthew G. Knepley PetscErrorCode VecGetCeedVectorRead(Vec X, Ceed ceed, CeedVector *cx) 707ce467fcSMatthew G. Knepley { 717ce467fcSMatthew G. Knepley PetscMemType memtype; 727ce467fcSMatthew G. Knepley const PetscScalar *x; 737ce467fcSMatthew G. Knepley PetscInt n; 74*4d86920dSPierre Jolivet 757ce467fcSMatthew G. Knepley PetscFunctionBegin; 767ce467fcSMatthew G. Knepley PetscCall(VecGetLocalSize(X, &n)); 777ce467fcSMatthew G. Knepley PetscCall(VecGetArrayReadAndMemType(X, &x, &memtype)); 787ce467fcSMatthew G. Knepley PetscCallCEED(CeedVectorCreate(ceed, n, cx)); 797ce467fcSMatthew G. Knepley PetscCallCEED(CeedVectorSetArray(*cx, PetscMemType2Ceed(memtype), CEED_USE_POINTER, (PetscScalar *)x)); 80d2b2dc1eSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 817ce467fcSMatthew G. Knepley } 827ce467fcSMatthew G. Knepley 837ce467fcSMatthew G. Knepley PetscErrorCode VecRestoreCeedVectorRead(Vec X, CeedVector *cx) 847ce467fcSMatthew G. Knepley { 857ce467fcSMatthew G. Knepley PetscFunctionBegin; 867ce467fcSMatthew G. Knepley PetscCall(VecRestoreArrayReadAndMemType(X, NULL)); 877ce467fcSMatthew G. Knepley PetscCallCEED(CeedVectorDestroy(cx)); 88d2b2dc1eSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 89d2b2dc1eSMatthew G. Knepley } 90d2b2dc1eSMatthew G. Knepley 91d2b2dc1eSMatthew G. Knepley CEED_QFUNCTION(Geometry2D)(void *ctx, const CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) 92d2b2dc1eSMatthew G. Knepley { 93d2b2dc1eSMatthew G. Knepley const CeedScalar *x = in[0], *Jac = in[1], *w = in[2]; 94d2b2dc1eSMatthew G. Knepley CeedScalar *qdata = out[0]; 95d2b2dc1eSMatthew G. Knepley 96d2b2dc1eSMatthew G. Knepley CeedPragmaSIMD for (CeedInt i = 0; i < Q; ++i) 97d2b2dc1eSMatthew G. Knepley { 98d2b2dc1eSMatthew G. Knepley const CeedScalar J[2][2] = { 99d2b2dc1eSMatthew G. Knepley {Jac[i + Q * 0], Jac[i + Q * 2]}, 100d2b2dc1eSMatthew G. Knepley {Jac[i + Q * 1], Jac[i + Q * 3]} 101d2b2dc1eSMatthew G. Knepley }; 102d2b2dc1eSMatthew G. Knepley const CeedScalar det = J[0][0] * J[1][1] - J[0][1] * J[1][0]; 103d2b2dc1eSMatthew G. Knepley 104d2b2dc1eSMatthew G. Knepley qdata[i + Q * 0] = det * w[i]; 105d2b2dc1eSMatthew G. Knepley qdata[i + Q * 1] = x[i + Q * 0]; 106d2b2dc1eSMatthew G. Knepley qdata[i + Q * 2] = x[i + Q * 1]; 107d2b2dc1eSMatthew G. Knepley qdata[i + Q * 3] = J[1][1] / det; 108d2b2dc1eSMatthew G. Knepley qdata[i + Q * 4] = -J[1][0] / det; 109d2b2dc1eSMatthew G. Knepley qdata[i + Q * 5] = -J[0][1] / det; 110d2b2dc1eSMatthew G. Knepley qdata[i + Q * 6] = J[0][0] / det; 111d2b2dc1eSMatthew G. Knepley } 112d2b2dc1eSMatthew G. Knepley return CEED_ERROR_SUCCESS; 113d2b2dc1eSMatthew G. Knepley } 114d2b2dc1eSMatthew G. Knepley 115d2b2dc1eSMatthew G. Knepley CEED_QFUNCTION(Geometry3D)(void *ctx, const CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) 116d2b2dc1eSMatthew G. Knepley { 117d2b2dc1eSMatthew G. Knepley const CeedScalar *Jac = in[1], *w = in[2]; 118d2b2dc1eSMatthew G. Knepley CeedScalar *qdata = out[0]; 119d2b2dc1eSMatthew G. Knepley 120d2b2dc1eSMatthew G. Knepley CeedPragmaSIMD for (CeedInt i = 0; i < Q; ++i) 121d2b2dc1eSMatthew G. Knepley { 122d2b2dc1eSMatthew G. Knepley const CeedScalar J[3][3] = { 123d2b2dc1eSMatthew G. Knepley {Jac[i + Q * 0], Jac[i + Q * 3], Jac[i + Q * 6]}, 124d2b2dc1eSMatthew G. Knepley {Jac[i + Q * 1], Jac[i + Q * 4], Jac[i + Q * 7]}, 125d2b2dc1eSMatthew G. Knepley {Jac[i + Q * 2], Jac[i + Q * 5], Jac[i + Q * 8]} 126d2b2dc1eSMatthew G. Knepley }; 127d2b2dc1eSMatthew G. Knepley const CeedScalar det = J[0][0] * (J[1][1] * J[2][2] - J[1][2] * J[2][1]) + J[0][1] * (J[1][2] * J[2][0] - J[1][0] * J[2][2]) + J[0][2] * (J[1][0] * J[2][1] - J[1][1] * J[2][0]); 128d2b2dc1eSMatthew G. Knepley 129d2b2dc1eSMatthew G. Knepley qdata[i + Q * 0] = det * w[i]; /* det J * weight */ 130d2b2dc1eSMatthew G. Knepley } 131d2b2dc1eSMatthew G. Knepley return CEED_ERROR_SUCCESS; 132d2b2dc1eSMatthew G. Knepley } 133d2b2dc1eSMatthew G. Knepley 134d2b2dc1eSMatthew G. Knepley static PetscErrorCode DMCeedCreateGeometry(DM dm, IS cellIS, PetscInt *Nqdata, CeedElemRestriction *erq, CeedVector *qd, DMCeed *soldata) 135d2b2dc1eSMatthew G. Knepley { 136d2b2dc1eSMatthew G. Knepley Ceed ceed; 137d2b2dc1eSMatthew G. Knepley DMCeed sd; 138d2b2dc1eSMatthew G. Knepley PetscDS ds; 139d2b2dc1eSMatthew G. Knepley PetscFE fe; 140d2b2dc1eSMatthew G. Knepley CeedQFunctionUser geom = NULL; 141d2b2dc1eSMatthew G. Knepley const char *geomName = NULL; 142d2b2dc1eSMatthew G. Knepley const PetscInt *cells; 14385f1dce8SJed Brown PetscInt dim, cdim, cStart, cEnd, Ncell; 14485f1dce8SJed Brown CeedInt Nq; 145d2b2dc1eSMatthew G. Knepley 146d2b2dc1eSMatthew G. Knepley PetscFunctionBegin; 147d2b2dc1eSMatthew G. Knepley PetscCall(PetscCalloc1(1, &sd)); 148d2b2dc1eSMatthew G. Knepley PetscCall(DMGetDimension(dm, &dim)); 149d2b2dc1eSMatthew G. Knepley PetscCall(DMGetCoordinateDim(dm, &cdim)); 150d2b2dc1eSMatthew G. Knepley PetscCall(DMGetCeed(dm, &ceed)); 151d2b2dc1eSMatthew G. Knepley PetscCall(ISGetPointRange(cellIS, &cStart, &cEnd, &cells)); 152d2b2dc1eSMatthew G. Knepley Ncell = cEnd - cStart; 153d2b2dc1eSMatthew G. Knepley 154d2b2dc1eSMatthew G. Knepley PetscCall(DMGetCellDS(dm, cells ? cells[cStart] : cStart, &ds, NULL)); 155d2b2dc1eSMatthew G. Knepley PetscCall(PetscDSGetDiscretization(ds, 0, (PetscObject *)&fe)); 156d2b2dc1eSMatthew G. Knepley PetscCall(PetscFEGetCeedBasis(fe, &sd->basis)); 157d2b2dc1eSMatthew G. Knepley PetscCall(CeedBasisGetNumQuadraturePoints(sd->basis, &Nq)); 158d2b2dc1eSMatthew G. Knepley PetscCall(DMPlexGetCeedRestriction(dm, NULL, 0, 0, 0, &sd->er)); 159d2b2dc1eSMatthew G. Knepley 1605962854dSMatthew G. Knepley *Nqdata = 1 + cdim + cdim * dim; // |J| * w_q, x, J^{-1} 161d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedElemRestrictionCreateStrided(ceed, Ncell, Nq, *Nqdata, Ncell * Nq * (*Nqdata), CEED_STRIDES_BACKEND, erq)); 162d2b2dc1eSMatthew G. Knepley 163d2b2dc1eSMatthew G. Knepley switch (dim) { 164d2b2dc1eSMatthew G. Knepley case 2: 165d2b2dc1eSMatthew G. Knepley geom = Geometry2D; 166d2b2dc1eSMatthew G. Knepley geomName = Geometry2D_loc; 167d2b2dc1eSMatthew G. Knepley break; 168d2b2dc1eSMatthew G. Knepley case 3: 169d2b2dc1eSMatthew G. Knepley geom = Geometry3D; 170d2b2dc1eSMatthew G. Knepley geomName = Geometry3D_loc; 171d2b2dc1eSMatthew G. Knepley break; 172d2b2dc1eSMatthew G. Knepley } 173d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedQFunctionCreateInterior(ceed, 1, geom, geomName, &sd->qf)); 174d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedQFunctionAddInput(sd->qf, "x", cdim, CEED_EVAL_INTERP)); 175d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedQFunctionAddInput(sd->qf, "dx", cdim * dim, CEED_EVAL_GRAD)); 176d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedQFunctionAddInput(sd->qf, "weight", 1, CEED_EVAL_WEIGHT)); 177d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedQFunctionAddOutput(sd->qf, "qdata", *Nqdata, CEED_EVAL_NONE)); 178d2b2dc1eSMatthew G. Knepley 179d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedOperatorCreate(ceed, sd->qf, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &sd->op)); 180d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedOperatorSetField(sd->op, "x", sd->er, sd->basis, CEED_VECTOR_ACTIVE)); 181d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedOperatorSetField(sd->op, "dx", sd->er, sd->basis, CEED_VECTOR_ACTIVE)); 182d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedOperatorSetField(sd->op, "weight", CEED_ELEMRESTRICTION_NONE, sd->basis, CEED_VECTOR_NONE)); 18310ae67c6SJeremy L Thompson PetscCallCEED(CeedOperatorSetField(sd->op, "qdata", *erq, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE)); 184d2b2dc1eSMatthew G. Knepley 185d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedElemRestrictionCreateVector(*erq, qd, NULL)); 186d2b2dc1eSMatthew G. Knepley *soldata = sd; 187d2b2dc1eSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 188d2b2dc1eSMatthew G. Knepley } 189d2b2dc1eSMatthew G. Knepley 190d2b2dc1eSMatthew G. Knepley PetscErrorCode DMRefineHook_Ceed(DM coarse, DM fine, void *ctx) 191d2b2dc1eSMatthew G. Knepley { 192d2b2dc1eSMatthew G. Knepley PetscFunctionBegin; 193d2b2dc1eSMatthew G. Knepley if (coarse->dmceed) PetscCall(DMCeedCreate(fine, coarse->dmceed->geom ? PETSC_TRUE : PETSC_FALSE, coarse->dmceed->func, coarse->dmceed->funcSource)); 194d2b2dc1eSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 195d2b2dc1eSMatthew G. Knepley } 196d2b2dc1eSMatthew G. Knepley 197d2b2dc1eSMatthew G. Knepley PetscErrorCode DMCeedCreate_Internal(DM dm, IS cellIS, PetscBool createGeometry, CeedQFunctionUser func, const char *func_source, DMCeed *soldata) 198d2b2dc1eSMatthew G. Knepley { 199d2b2dc1eSMatthew G. Knepley PetscDS ds; 200d2b2dc1eSMatthew G. Knepley PetscFE fe; 201d2b2dc1eSMatthew G. Knepley DMCeed sd; 202d2b2dc1eSMatthew G. Knepley Ceed ceed; 20385f1dce8SJed Brown PetscInt dim, Nc, Nqdata = 0; 20485f1dce8SJed Brown CeedInt Nq; 205d2b2dc1eSMatthew G. Knepley 206d2b2dc1eSMatthew G. Knepley PetscFunctionBegin; 207d2b2dc1eSMatthew G. Knepley PetscCall(PetscCalloc1(1, &sd)); 208d2b2dc1eSMatthew G. Knepley PetscCall(DMGetDimension(dm, &dim)); 209d2b2dc1eSMatthew G. Knepley PetscCall(DMGetCeed(dm, &ceed)); 210d2b2dc1eSMatthew G. Knepley PetscCall(DMGetDS(dm, &ds)); 211d2b2dc1eSMatthew G. Knepley PetscCall(PetscDSGetDiscretization(ds, 0, (PetscObject *)&fe)); 212d2b2dc1eSMatthew G. Knepley PetscCall(PetscFEGetCeedBasis(fe, &sd->basis)); 213d2b2dc1eSMatthew G. Knepley PetscCall(PetscFEGetNumComponents(fe, &Nc)); 214d2b2dc1eSMatthew G. Knepley PetscCall(CeedBasisGetNumQuadraturePoints(sd->basis, &Nq)); 215d2b2dc1eSMatthew G. Knepley PetscCall(DMPlexGetCeedRestriction(dm, NULL, 0, 0, 0, &sd->er)); 216d2b2dc1eSMatthew G. Knepley 217d2b2dc1eSMatthew G. Knepley if (createGeometry) { 218d2b2dc1eSMatthew G. Knepley DM cdm; 219d2b2dc1eSMatthew G. Knepley 220d2b2dc1eSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &cdm)); 221d2b2dc1eSMatthew G. Knepley PetscCall(DMCeedCreateGeometry(cdm, cellIS, &Nqdata, &sd->erq, &sd->qd, &sd->geom)); 222d2b2dc1eSMatthew G. Knepley } 223d2b2dc1eSMatthew G. Knepley 224d2b2dc1eSMatthew G. Knepley if (sd->geom) { 22585f1dce8SJed Brown PetscInt cdim; 22685f1dce8SJed Brown CeedInt Nqx; 227d2b2dc1eSMatthew G. Knepley 228d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedBasisGetNumQuadraturePoints(sd->geom->basis, &Nqx)); 22985f1dce8SJed Brown PetscCheck(Nqx == Nq, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_INCOMP, "Number of qpoints for solution %" CeedInt_FMT " != %" CeedInt_FMT " Number of qpoints for coordinates", Nq, Nqx); 230d2b2dc1eSMatthew G. Knepley /* TODO Remove this limitation */ 231d2b2dc1eSMatthew G. Knepley PetscCall(DMGetCoordinateDim(dm, &cdim)); 232d2b2dc1eSMatthew G. Knepley PetscCheck(dim == cdim, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_INCOMP, "Topological dimension %" PetscInt_FMT " != %" PetscInt_FMT " embedding dimension", dim, cdim); 233d2b2dc1eSMatthew G. Knepley } 234d2b2dc1eSMatthew G. Knepley 235d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedQFunctionCreateInterior(ceed, 1, func, func_source, &sd->qf)); 236d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedQFunctionAddInput(sd->qf, "u", Nc, CEED_EVAL_INTERP)); 237d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedQFunctionAddInput(sd->qf, "du", Nc * dim, CEED_EVAL_GRAD)); 238d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedQFunctionAddInput(sd->qf, "qdata", Nqdata, CEED_EVAL_NONE)); 239d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedQFunctionAddOutput(sd->qf, "v", Nc, CEED_EVAL_INTERP)); 240d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedQFunctionAddOutput(sd->qf, "dv", Nc * dim, CEED_EVAL_GRAD)); 241d2b2dc1eSMatthew G. Knepley 242d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedOperatorCreate(ceed, sd->qf, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &sd->op)); 243d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedOperatorSetField(sd->op, "u", sd->er, sd->basis, CEED_VECTOR_ACTIVE)); 244d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedOperatorSetField(sd->op, "du", sd->er, sd->basis, CEED_VECTOR_ACTIVE)); 24510ae67c6SJeremy L Thompson PetscCallCEED(CeedOperatorSetField(sd->op, "qdata", sd->erq, CEED_BASIS_NONE, sd->qd)); 246d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedOperatorSetField(sd->op, "v", sd->er, sd->basis, CEED_VECTOR_ACTIVE)); 247d2b2dc1eSMatthew G. Knepley PetscCallCEED(CeedOperatorSetField(sd->op, "dv", sd->er, sd->basis, CEED_VECTOR_ACTIVE)); 248d2b2dc1eSMatthew G. Knepley 249d2b2dc1eSMatthew G. Knepley // Handle refinement 250d2b2dc1eSMatthew G. Knepley sd->func = func; 251d2b2dc1eSMatthew G. Knepley PetscCall(PetscStrallocpy(func_source, &sd->funcSource)); 252d2b2dc1eSMatthew G. Knepley PetscCall(DMRefineHookAdd(dm, DMRefineHook_Ceed, NULL, NULL)); 253d2b2dc1eSMatthew G. Knepley 254d2b2dc1eSMatthew G. Knepley *soldata = sd; 255d2b2dc1eSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 256d2b2dc1eSMatthew G. Knepley } 257d2b2dc1eSMatthew G. Knepley 258d2b2dc1eSMatthew G. Knepley PetscErrorCode DMCeedCreate(DM dm, PetscBool createGeometry, CeedQFunctionUser func, const char *func_source) 259d2b2dc1eSMatthew G. Knepley { 260d2b2dc1eSMatthew G. Knepley DM plex; 261d2b2dc1eSMatthew G. Knepley IS cellIS; 262d2b2dc1eSMatthew G. Knepley 263d2b2dc1eSMatthew G. Knepley PetscFunctionBegin; 264d2b2dc1eSMatthew G. Knepley PetscCall(DMConvert(dm, DMPLEX, &plex)); 265d2b2dc1eSMatthew G. Knepley PetscCall(DMPlexGetAllCells_Internal(plex, &cellIS)); 266d2b2dc1eSMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 267d2b2dc1eSMatthew G. Knepley PetscCall(DMCeedCreate_Internal(dm, cellIS, createGeometry, func, func_source, &dm->dmceed)); 268d2b2dc1eSMatthew G. Knepley #endif 269d2b2dc1eSMatthew G. Knepley PetscCall(ISDestroy(&cellIS)); 270d2b2dc1eSMatthew G. Knepley PetscCall(DMDestroy(&plex)); 271d2b2dc1eSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 2727ce467fcSMatthew G. Knepley } 2737ce467fcSMatthew G. Knepley 2745962854dSMatthew G. Knepley static PetscErrorCode DMCeedCreateGeometryFVM(DM dm, IS faceIS, PetscInt *Nqdata, CeedElemRestriction *erq, CeedVector *qd, DMCeed *soldata) 2755962854dSMatthew G. Knepley { 2765962854dSMatthew G. Knepley Ceed ceed; 2775962854dSMatthew G. Knepley DMCeed sd; 2785962854dSMatthew G. Knepley const PetscInt *faces; 279a2bd4c7eSAlbert Cowie CeedInt strides[3]; 2805962854dSMatthew G. Knepley PetscInt dim, cdim, fStart, fEnd, Nface, Nq = 1; 2815962854dSMatthew G. Knepley 2825962854dSMatthew G. Knepley PetscFunctionBegin; 2835962854dSMatthew G. Knepley PetscCall(PetscCalloc1(1, &sd)); 2845962854dSMatthew G. Knepley PetscCall(DMGetDimension(dm, &dim)); 2855962854dSMatthew G. Knepley PetscCall(DMGetCoordinateDim(dm, &cdim)); 2865962854dSMatthew G. Knepley PetscCall(DMGetCeed(dm, &ceed)); 2875962854dSMatthew G. Knepley PetscCall(ISGetPointRange(faceIS, &fStart, &fEnd, &faces)); 2885962854dSMatthew G. Knepley Nface = fEnd - fStart; 2895962854dSMatthew G. Knepley 2905962854dSMatthew G. Knepley *Nqdata = cdim + 2; // face normal and support cell volumes 291a2bd4c7eSAlbert Cowie strides[0] = 1; 292a2bd4c7eSAlbert Cowie strides[1] = Nq; 293a2bd4c7eSAlbert Cowie strides[2] = Nq * (*Nqdata); 294a2bd4c7eSAlbert Cowie PetscCallCEED(CeedElemRestrictionCreateStrided(ceed, Nface, Nq, *Nqdata, Nface * Nq * (*Nqdata), strides, erq)); 2955962854dSMatthew G. Knepley PetscCallCEED(CeedElemRestrictionCreateVector(*erq, qd, NULL)); 2965962854dSMatthew G. Knepley *soldata = sd; 2975962854dSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 2985962854dSMatthew G. Knepley } 2995962854dSMatthew G. Knepley 300354b609cSMatthew G. Knepley static PetscErrorCode DMCeedCreateInfoFVM(DM dm, IS faceIS, PetscInt *Nqinfo, CeedElemRestriction *eri, CeedVector *qi, DMCeed *solinfo) 301354b609cSMatthew G. Knepley { 302354b609cSMatthew G. Knepley Ceed ceed; 303354b609cSMatthew G. Knepley DMCeed si; 304354b609cSMatthew G. Knepley const PetscInt *faces; 305a2bd4c7eSAlbert Cowie CeedInt strides[3]; 306354b609cSMatthew G. Knepley PetscInt dim, fStart, fEnd, Nface, Nq = 1; 307354b609cSMatthew G. Knepley 308354b609cSMatthew G. Knepley PetscFunctionBegin; 309354b609cSMatthew G. Knepley PetscCall(PetscCalloc1(1, &si)); 310354b609cSMatthew G. Knepley PetscCall(DMGetDimension(dm, &dim)); 311354b609cSMatthew G. Knepley PetscCall(DMGetCeed(dm, &ceed)); 312354b609cSMatthew G. Knepley PetscCall(ISGetPointRange(faceIS, &fStart, &fEnd, &faces)); 313354b609cSMatthew G. Knepley Nface = fEnd - fStart; 314354b609cSMatthew G. Knepley 315354b609cSMatthew G. Knepley *Nqinfo = 3; // face number and support cell numbers 316a2bd4c7eSAlbert Cowie strides[0] = 1; 317a2bd4c7eSAlbert Cowie strides[1] = Nq; 318a2bd4c7eSAlbert Cowie strides[2] = Nq * (*Nqinfo); 319a2bd4c7eSAlbert Cowie PetscCallCEED(CeedElemRestrictionCreateStrided(ceed, Nface, Nq, *Nqinfo, Nface * Nq * (*Nqinfo), strides, eri)); 320354b609cSMatthew G. Knepley PetscCallCEED(CeedElemRestrictionCreateVector(*eri, qi, NULL)); 321354b609cSMatthew G. Knepley *solinfo = si; 322354b609cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 323354b609cSMatthew G. Knepley } 324354b609cSMatthew G. Knepley 325354b609cSMatthew G. Knepley PetscErrorCode DMCeedCreateFVM_Internal(DM dm, IS faceIS, PetscBool createGeometry, PetscBool createInfo, CeedQFunctionUser func, const char *func_source, DMCeed *soldata, CeedQFunctionContext qfCtx) 3265962854dSMatthew G. Knepley { 3275962854dSMatthew G. Knepley PetscDS ds; 3285962854dSMatthew G. Knepley PetscFV fv; 3295962854dSMatthew G. Knepley DMCeed sd; 3305962854dSMatthew G. Knepley Ceed ceed; 331354b609cSMatthew G. Knepley PetscInt dim, Nc, Nqdata = 0, Nqinfo = 0; 3325962854dSMatthew G. Knepley 3335962854dSMatthew G. Knepley PetscFunctionBegin; 3345962854dSMatthew G. Knepley PetscCall(PetscCalloc1(1, &sd)); 3355962854dSMatthew G. Knepley PetscCall(DMGetDimension(dm, &dim)); 3365962854dSMatthew G. Knepley PetscCall(DMGetCeed(dm, &ceed)); 3375962854dSMatthew G. Knepley PetscCall(DMGetDS(dm, &ds)); 3385962854dSMatthew G. Knepley PetscCall(PetscDSGetDiscretization(ds, 0, (PetscObject *)&fv)); 3395962854dSMatthew G. Knepley PetscCall(PetscFVGetNumComponents(fv, &Nc)); 3405962854dSMatthew G. Knepley PetscCall(DMPlexCreateCeedRestrictionFVM(dm, &sd->erL, &sd->erR)); 3415962854dSMatthew G. Knepley 3425962854dSMatthew G. Knepley if (createGeometry) { 3435962854dSMatthew G. Knepley DM cdm; 3445962854dSMatthew G. Knepley 3455962854dSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &cdm)); 3465962854dSMatthew G. Knepley PetscCall(DMCeedCreateGeometryFVM(cdm, faceIS, &Nqdata, &sd->erq, &sd->qd, &sd->geom)); 3475962854dSMatthew G. Knepley } 3485962854dSMatthew G. Knepley 349354b609cSMatthew G. Knepley if (createInfo) { 350354b609cSMatthew G. Knepley DM cdm; 351354b609cSMatthew G. Knepley 352354b609cSMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &cdm)); 353354b609cSMatthew G. Knepley PetscCall(DMCeedCreateInfoFVM(cdm, faceIS, &Nqinfo, &sd->eri, &sd->qi, &sd->info)); 354354b609cSMatthew G. Knepley PetscCall(DMCeedComputeInfo(dm, sd)); 355354b609cSMatthew G. Knepley } 356354b609cSMatthew G. Knepley 3575962854dSMatthew G. Knepley PetscCallCEED(CeedQFunctionCreateInterior(ceed, 1, func, func_source, &sd->qf)); 3585962854dSMatthew G. Knepley PetscCallCEED(CeedQFunctionAddInput(sd->qf, "uL", Nc, CEED_EVAL_NONE)); 3595962854dSMatthew G. Knepley PetscCallCEED(CeedQFunctionAddInput(sd->qf, "uR", Nc, CEED_EVAL_NONE)); 3605962854dSMatthew G. Knepley PetscCallCEED(CeedQFunctionAddInput(sd->qf, "geom", Nqdata, CEED_EVAL_NONE)); 361354b609cSMatthew G. Knepley if (createInfo) PetscCallCEED(CeedQFunctionAddInput(sd->qf, "info", Nqinfo, CEED_EVAL_NONE)); 3625962854dSMatthew G. Knepley PetscCallCEED(CeedQFunctionAddOutput(sd->qf, "cL", Nc, CEED_EVAL_NONE)); 3635962854dSMatthew G. Knepley PetscCallCEED(CeedQFunctionAddOutput(sd->qf, "cR", Nc, CEED_EVAL_NONE)); 3645962854dSMatthew G. Knepley 3655962854dSMatthew G. Knepley PetscCallCEED(CeedQFunctionSetContext(sd->qf, qfCtx)); 3665962854dSMatthew G. Knepley 3675962854dSMatthew G. Knepley PetscCallCEED(CeedOperatorCreate(ceed, sd->qf, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &sd->op)); 36810ae67c6SJeremy L Thompson PetscCallCEED(CeedOperatorSetField(sd->op, "uL", sd->erL, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE)); 36910ae67c6SJeremy L Thompson PetscCallCEED(CeedOperatorSetField(sd->op, "uR", sd->erR, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE)); 37010ae67c6SJeremy L Thompson PetscCallCEED(CeedOperatorSetField(sd->op, "geom", sd->erq, CEED_BASIS_NONE, sd->qd)); 371354b609cSMatthew G. Knepley if (createInfo) PetscCallCEED(CeedOperatorSetField(sd->op, "info", sd->eri, CEED_BASIS_NONE, sd->qi)); 37210ae67c6SJeremy L Thompson PetscCallCEED(CeedOperatorSetField(sd->op, "cL", sd->erL, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE)); 37310ae67c6SJeremy L Thompson PetscCallCEED(CeedOperatorSetField(sd->op, "cR", sd->erR, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE)); 3745962854dSMatthew G. Knepley 3755962854dSMatthew G. Knepley // Handle refinement 3765962854dSMatthew G. Knepley sd->func = func; 3775962854dSMatthew G. Knepley PetscCall(PetscStrallocpy(func_source, &sd->funcSource)); 3785962854dSMatthew G. Knepley PetscCall(DMRefineHookAdd(dm, DMRefineHook_Ceed, NULL, NULL)); 3795962854dSMatthew G. Knepley 3805962854dSMatthew G. Knepley *soldata = sd; 3815962854dSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 3825962854dSMatthew G. Knepley } 3835962854dSMatthew G. Knepley 3845962854dSMatthew G. Knepley PetscErrorCode DMCeedCreateFVM(DM dm, PetscBool createGeometry, CeedQFunctionUser func, const char *func_source, CeedQFunctionContext qfCtx) 3855962854dSMatthew G. Knepley { 3865962854dSMatthew G. Knepley DM plex; 3875962854dSMatthew G. Knepley IS faceIS; 3885962854dSMatthew G. Knepley 3895962854dSMatthew G. Knepley PetscFunctionBegin; 3905962854dSMatthew G. Knepley PetscCall(DMConvert(dm, DMPLEX, &plex)); 3915962854dSMatthew G. Knepley PetscCall(DMPlexGetAllFaces_Internal(plex, &faceIS)); 3925962854dSMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 393354b609cSMatthew G. Knepley PetscCall(DMCeedCreateFVM_Internal(dm, faceIS, createGeometry, PETSC_TRUE, func, func_source, &dm->dmceed, qfCtx)); 3945962854dSMatthew G. Knepley #endif 3955962854dSMatthew G. Knepley PetscCall(ISDestroy(&faceIS)); 3965962854dSMatthew G. Knepley PetscCall(DMDestroy(&plex)); 3975962854dSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 3985962854dSMatthew G. Knepley } 3995962854dSMatthew G. Knepley 400f918ec44SMatthew G. Knepley #endif 401d2b2dc1eSMatthew G. Knepley 402d2b2dc1eSMatthew G. Knepley PetscErrorCode DMCeedDestroy(DMCeed *pceed) 403d2b2dc1eSMatthew G. Knepley { 404d2b2dc1eSMatthew G. Knepley DMCeed p = *pceed; 405d2b2dc1eSMatthew G. Knepley 406d2b2dc1eSMatthew G. Knepley PetscFunctionBegin; 407d2b2dc1eSMatthew G. Knepley if (!p) PetscFunctionReturn(PETSC_SUCCESS); 408d2b2dc1eSMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 409d2b2dc1eSMatthew G. Knepley PetscCall(PetscFree(p->funcSource)); 410d2b2dc1eSMatthew G. Knepley if (p->qd) PetscCallCEED(CeedVectorDestroy(&p->qd)); 411354b609cSMatthew G. Knepley if (p->qi) PetscCallCEED(CeedVectorDestroy(&p->qi)); 412d2b2dc1eSMatthew G. Knepley if (p->op) PetscCallCEED(CeedOperatorDestroy(&p->op)); 413d2b2dc1eSMatthew G. Knepley if (p->qf) PetscCallCEED(CeedQFunctionDestroy(&p->qf)); 4145962854dSMatthew G. Knepley if (p->erL) PetscCallCEED(CeedElemRestrictionDestroy(&p->erL)); 4155962854dSMatthew G. Knepley if (p->erR) PetscCallCEED(CeedElemRestrictionDestroy(&p->erR)); 416d2b2dc1eSMatthew G. Knepley if (p->erq) PetscCallCEED(CeedElemRestrictionDestroy(&p->erq)); 417354b609cSMatthew G. Knepley if (p->eri) PetscCallCEED(CeedElemRestrictionDestroy(&p->eri)); 418d2b2dc1eSMatthew G. Knepley PetscCall(DMCeedDestroy(&p->geom)); 419354b609cSMatthew G. Knepley PetscCall(DMCeedDestroy(&p->info)); 420d2b2dc1eSMatthew G. Knepley #endif 421d2b2dc1eSMatthew G. Knepley PetscCall(PetscFree(p)); 422d2b2dc1eSMatthew G. Knepley *pceed = NULL; 423d2b2dc1eSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 424d2b2dc1eSMatthew G. Knepley } 425d2b2dc1eSMatthew G. Knepley 426d2b2dc1eSMatthew G. Knepley PetscErrorCode DMCeedComputeGeometry(DM dm, DMCeed sd) 427d2b2dc1eSMatthew G. Knepley { 428d2b2dc1eSMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 429d2b2dc1eSMatthew G. Knepley Ceed ceed; 430d2b2dc1eSMatthew G. Knepley Vec coords; 431d2b2dc1eSMatthew G. Knepley CeedVector ccoords; 432d2b2dc1eSMatthew G. Knepley #endif 433d2b2dc1eSMatthew G. Knepley 434d2b2dc1eSMatthew G. Knepley PetscFunctionBegin; 435d2b2dc1eSMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 436d2b2dc1eSMatthew G. Knepley PetscCall(DMGetCeed(dm, &ceed)); 437d2b2dc1eSMatthew G. Knepley PetscCall(DMGetCoordinatesLocal(dm, &coords)); 438d2b2dc1eSMatthew G. Knepley PetscCall(VecGetCeedVectorRead(coords, ceed, &ccoords)); 4395962854dSMatthew G. Knepley if (sd->geom->op) PetscCallCEED(CeedOperatorApply(sd->geom->op, ccoords, sd->qd, CEED_REQUEST_IMMEDIATE)); 4405962854dSMatthew G. Knepley else PetscCall(DMPlexCeedComputeGeometryFVM(dm, sd->qd)); 4415962854dSMatthew G. Knepley //PetscCallCEED(CeedVectorView(sd->qd, "%g", stdout)); 442d2b2dc1eSMatthew G. Knepley PetscCall(VecRestoreCeedVectorRead(coords, &ccoords)); 443d2b2dc1eSMatthew G. Knepley #endif 444d2b2dc1eSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 445d2b2dc1eSMatthew G. Knepley } 446354b609cSMatthew G. Knepley 447354b609cSMatthew G. Knepley PetscErrorCode DMCeedComputeInfo(DM dm, DMCeed sd) 448354b609cSMatthew G. Knepley { 449354b609cSMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 450354b609cSMatthew G. Knepley CeedScalar *a; 451354b609cSMatthew G. Knepley #endif 452354b609cSMatthew G. Knepley 453354b609cSMatthew G. Knepley PetscFunctionBegin; 454354b609cSMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 455354b609cSMatthew G. Knepley PetscCallCEED(CeedVectorGetArrayWrite(sd->qi, CEED_MEM_HOST, &a)); 456354b609cSMatthew G. Knepley 457354b609cSMatthew G. Knepley IS iterIS; 458354b609cSMatthew G. Knepley DMLabel label = NULL; 459354b609cSMatthew G. Knepley const PetscInt *indices; 460354b609cSMatthew G. Knepley PetscInt value = 0, height = 1, NfInt = 0, Nf = 0; 461354b609cSMatthew G. Knepley 462354b609cSMatthew G. Knepley PetscCall(DMGetPoints_Internal(dm, label, value, height, &iterIS)); 463354b609cSMatthew G. Knepley if (iterIS) { 464354b609cSMatthew G. Knepley PetscCall(ISGetIndices(iterIS, &indices)); 465354b609cSMatthew G. Knepley PetscCall(ISGetLocalSize(iterIS, &Nf)); 466354b609cSMatthew G. Knepley for (PetscInt p = 0, Ns; p < Nf; ++p) { 467354b609cSMatthew G. Knepley PetscCall(DMPlexGetSupportSize(dm, indices[p], &Ns)); 468354b609cSMatthew G. Knepley if (Ns == 2) ++NfInt; 469354b609cSMatthew G. Knepley } 470354b609cSMatthew G. Knepley } else { 471354b609cSMatthew G. Knepley indices = NULL; 472354b609cSMatthew G. Knepley } 473354b609cSMatthew G. Knepley 474354b609cSMatthew G. Knepley PetscInt infoOffset = 0; 475354b609cSMatthew G. Knepley 476354b609cSMatthew G. Knepley for (PetscInt p = 0; p < Nf; ++p) { 477354b609cSMatthew G. Knepley const PetscInt face = indices[p]; 478354b609cSMatthew G. Knepley const PetscInt *supp; 479354b609cSMatthew G. Knepley PetscInt Ns; 480354b609cSMatthew G. Knepley 481354b609cSMatthew G. Knepley PetscCall(DMPlexGetSupport(dm, face, &supp)); 482354b609cSMatthew G. Knepley PetscCall(DMPlexGetSupportSize(dm, face, &Ns)); 483354b609cSMatthew G. Knepley // Ignore boundary faces 484354b609cSMatthew G. Knepley // TODO check for face on parallel boundary 485354b609cSMatthew G. Knepley if (Ns == 2) { 486354b609cSMatthew G. Knepley a[infoOffset++] = face; 487354b609cSMatthew G. Knepley a[infoOffset++] = supp[0]; 488354b609cSMatthew G. Knepley a[infoOffset++] = supp[1]; 489354b609cSMatthew G. Knepley } 490354b609cSMatthew G. Knepley } 491354b609cSMatthew G. Knepley PetscCheck(infoOffset == NfInt * 3, PETSC_COMM_SELF, PETSC_ERR_SUP, "Shape mismatch, info offsets array of shape (%" PetscInt_FMT ") initialized for %" PetscInt_FMT " nodes", infoOffset, NfInt * 3); 492354b609cSMatthew G. Knepley if (iterIS) PetscCall(ISRestoreIndices(iterIS, &indices)); 493354b609cSMatthew G. Knepley PetscCall(ISDestroy(&iterIS)); 494354b609cSMatthew G. Knepley 495354b609cSMatthew G. Knepley PetscCallCEED(CeedVectorRestoreArray(sd->qi, &a)); 496354b609cSMatthew G. Knepley #endif 497354b609cSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 498354b609cSMatthew G. Knepley } 499