147923291SMatthew G. Knepley #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 247923291SMatthew G. Knepley 38c6c5593SMatthew G. Knepley #include <petsc/private/petscfeimpl.h> 48c6c5593SMatthew G. Knepley 5a6e0b375SMatthew G. Knepley /* 6a6e0b375SMatthew G. Knepley DMProjectPoint_Func_Private - Interpolate the given function in the output basis on the given point 7a6e0b375SMatthew G. Knepley 8a6e0b375SMatthew G. Knepley Input Parameters: 9a6e0b375SMatthew G. Knepley + dm - The output DM 10a6e0b375SMatthew G. Knepley . ds - The output DS 11a6e0b375SMatthew G. Knepley . dmIn - The input DM 12a6e0b375SMatthew G. Knepley . dsIn - The input DS 13a6e0b375SMatthew G. Knepley . time - The time for this evaluation 14a6e0b375SMatthew G. Knepley . fegeom - The FE geometry for this point 15a6e0b375SMatthew G. Knepley . fvgeom - The FV geometry for this point 16a6e0b375SMatthew G. Knepley . isFE - Flag indicating whether each output field has an FE discretization 17a6e0b375SMatthew G. Knepley . sp - The output PetscDualSpace for each field 18a6e0b375SMatthew G. Knepley . funcs - The evaluation function for each field 19a6e0b375SMatthew G. Knepley - ctxs - The user context for each field 20a6e0b375SMatthew G. Knepley 21a6e0b375SMatthew G. Knepley Output Parameter: 22a6e0b375SMatthew G. Knepley . values - The value for each dual basis vector in the output dual space 23a6e0b375SMatthew G. Knepley 24a6e0b375SMatthew G. Knepley Level: developer 25a6e0b375SMatthew G. Knepley 26a6e0b375SMatthew G. Knepley .seealso: DMProjectPoint_Field_Private() 27a6e0b375SMatthew G. Knepley */ 28a6e0b375SMatthew G. Knepley static PetscErrorCode DMProjectPoint_Func_Private(DM dm, PetscDS ds, DM dmIn, PetscDS dsIn, PetscReal time, PetscFEGeom *fegeom, PetscFVCellGeom *fvgeom, PetscBool isFE[], PetscDualSpace sp[], 298c6c5593SMatthew G. Knepley PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, 308c6c5593SMatthew G. Knepley PetscScalar values[]) 3147923291SMatthew G. Knepley { 32a6e0b375SMatthew G. Knepley PetscInt coordDim, Nf, *Nc, f, spDim, d, v, tp; 33ca3d3a14SMatthew G. Knepley PetscBool isAffine, transform; 348c6c5593SMatthew G. Knepley PetscErrorCode ierr; 358c6c5593SMatthew G. Knepley 368c6c5593SMatthew G. Knepley PetscFunctionBeginHot; 37a6e0b375SMatthew G. Knepley ierr = DMGetCoordinateDim(dmIn, &coordDim);CHKERRQ(ierr); 38a6e0b375SMatthew G. Knepley ierr = DMHasBasisTransform(dmIn, &transform);CHKERRQ(ierr); 39a6e0b375SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 40a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponents(ds, &Nc);CHKERRQ(ierr); 418c6c5593SMatthew G. Knepley /* Get values for closure */ 42c330f8ffSToby Isaac isAffine = fegeom->isAffine; 43c330f8ffSToby Isaac for (f = 0, v = 0, tp = 0; f < Nf; ++f) { 448c6c5593SMatthew G. Knepley void * const ctx = ctxs ? ctxs[f] : NULL; 458c6c5593SMatthew G. Knepley 468c6c5593SMatthew G. Knepley if (!sp[f]) continue; 478c6c5593SMatthew G. Knepley ierr = PetscDualSpaceGetDimension(sp[f], &spDim);CHKERRQ(ierr); 488c6c5593SMatthew G. Knepley if (funcs[f]) { 49c330f8ffSToby Isaac if (isFE[f]) { 50c330f8ffSToby Isaac PetscQuadrature allPoints; 51c330f8ffSToby Isaac PetscInt q, dim, numPoints; 52c330f8ffSToby Isaac const PetscReal *points; 53c330f8ffSToby Isaac PetscScalar *pointEval; 54c330f8ffSToby Isaac PetscReal *x; 55ca3d3a14SMatthew G. Knepley DM rdm; 56c330f8ffSToby Isaac 57ca3d3a14SMatthew G. Knepley ierr = PetscDualSpaceGetDM(sp[f],&rdm);CHKERRQ(ierr); 58c330f8ffSToby Isaac ierr = PetscDualSpaceGetAllPoints(sp[f], &allPoints);CHKERRQ(ierr); 59c330f8ffSToby Isaac ierr = PetscQuadratureGetData(allPoints,&dim,NULL,&numPoints,&points,NULL);CHKERRQ(ierr); 60ca3d3a14SMatthew G. Knepley ierr = DMGetWorkArray(rdm,numPoints*Nc[f],MPIU_SCALAR,&pointEval);CHKERRQ(ierr); 61ca3d3a14SMatthew G. Knepley ierr = DMGetWorkArray(rdm,coordDim,MPIU_REAL,&x);CHKERRQ(ierr); 62c330f8ffSToby Isaac for (q = 0; q < numPoints; q++, tp++) { 63c330f8ffSToby Isaac const PetscReal *v0; 64c330f8ffSToby Isaac 65c330f8ffSToby Isaac if (isAffine) { 66c330f8ffSToby Isaac CoordinatesRefToReal(coordDim, fegeom->dim, fegeom->xi, fegeom->v, fegeom->J, &points[q*dim], x); 67c330f8ffSToby Isaac v0 = x; 688c6c5593SMatthew G. Knepley } else { 69c330f8ffSToby Isaac v0 = &fegeom->v[tp*coordDim]; 708c6c5593SMatthew G. Knepley } 71a6e0b375SMatthew G. Knepley if (transform) {ierr = DMPlexBasisTransformApplyReal_Internal(dmIn, v0, PETSC_TRUE, coordDim, v0, x, dm->transformCtx);CHKERRQ(ierr); v0 = x;} 72c330f8ffSToby Isaac ierr = (*funcs[f])(coordDim, time, v0, Nc[f], &pointEval[Nc[f]*q], ctx);CHKERRQ(ierr); 73c330f8ffSToby Isaac } 744bee2e38SMatthew G. Knepley /* Transform point evaluations pointEval[q,c] */ 754bee2e38SMatthew G. Knepley ierr = PetscDualSpacePullback(sp[f], fegeom, numPoints, Nc[f], pointEval);CHKERRQ(ierr); 76c330f8ffSToby Isaac ierr = PetscDualSpaceApplyAll(sp[f], pointEval, &values[v]);CHKERRQ(ierr); 77ca3d3a14SMatthew G. Knepley ierr = DMRestoreWorkArray(rdm,coordDim,MPIU_REAL,&x);CHKERRQ(ierr); 78ca3d3a14SMatthew G. Knepley ierr = DMRestoreWorkArray(rdm,numPoints*Nc[f],MPIU_SCALAR,&pointEval);CHKERRQ(ierr); 79c330f8ffSToby Isaac v += spDim; 80c330f8ffSToby Isaac } else { 81c330f8ffSToby Isaac for (d = 0; d < spDim; ++d, ++v) { 82c330f8ffSToby Isaac ierr = PetscDualSpaceApplyFVM(sp[f], d, time, fvgeom, Nc[f], funcs[f], ctx, &values[v]);CHKERRQ(ierr); 83c330f8ffSToby Isaac } 84c330f8ffSToby Isaac } 85c330f8ffSToby Isaac } else { 86c330f8ffSToby Isaac for (d = 0; d < spDim; d++, v++) {values[v] = 0.0;} 878c6c5593SMatthew G. Knepley } 889c3cf19fSMatthew G. Knepley } 898c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 908c6c5593SMatthew G. Knepley } 918c6c5593SMatthew G. Knepley 92a6e0b375SMatthew G. Knepley /* 93a6e0b375SMatthew G. Knepley DMProjectPoint_Field_Private - Interpolate a function of the given field, in the input basis, using the output basis on the given point 94a6e0b375SMatthew G. Knepley 95a6e0b375SMatthew G. Knepley Input Parameters: 96a6e0b375SMatthew G. Knepley + dm - The output DM 97a6e0b375SMatthew G. Knepley . ds - The output DS 98a6e0b375SMatthew G. Knepley . dmIn - The input DM 99a6e0b375SMatthew G. Knepley . dsIn - The input DS 100a6e0b375SMatthew G. Knepley . dmAux - The auxiliary DM, which is always for the input space 101a6e0b375SMatthew G. Knepley . dsAux - The auxiliary DS, which is always for the input space 102a6e0b375SMatthew G. Knepley . time - The time for this evaluation 103a6e0b375SMatthew G. Knepley . localU - The local solution 104a6e0b375SMatthew G. Knepley . localA - The local auziliary fields 105a6e0b375SMatthew G. Knepley . cgeom - The FE geometry for this point 106a6e0b375SMatthew G. Knepley . sp - The output PetscDualSpace for each field 107a6e0b375SMatthew G. Knepley . p - The point in the output DM 108*ef0bb6c7SMatthew G. Knepley . T - Input basis and derviatives for each field tabulated on the quadrature points 109*ef0bb6c7SMatthew G. Knepley . TAux - Auxiliary basis and derivatives for each aux field tabulated on the quadrature points 110a6e0b375SMatthew G. Knepley . funcs - The evaluation function for each field 111a6e0b375SMatthew G. Knepley - ctxs - The user context for each field 112a6e0b375SMatthew G. Knepley 113a6e0b375SMatthew G. Knepley Output Parameter: 114a6e0b375SMatthew G. Knepley . values - The value for each dual basis vector in the output dual space 115a6e0b375SMatthew G. Knepley 116a6e0b375SMatthew G. Knepley Note: Not supported for FV 117a6e0b375SMatthew G. Knepley 118a6e0b375SMatthew G. Knepley Level: developer 119a6e0b375SMatthew G. Knepley 120a6e0b375SMatthew G. Knepley .seealso: DMProjectPoint_Field_Private() 121a6e0b375SMatthew G. Knepley */ 122a6e0b375SMatthew G. Knepley static PetscErrorCode DMProjectPoint_Field_Private(DM dm, PetscDS ds, DM dmIn, DMEnclosureType encIn, PetscDS dsIn, DM dmAux, DMEnclosureType encAux, PetscDS dsAux, PetscReal time, Vec localU, Vec localA, PetscFEGeom *cgeom, PetscDualSpace sp[], PetscInt p, 123*ef0bb6c7SMatthew G. Knepley PetscTabulation *T, PetscTabulation *TAux, 1248c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 1258c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 1268c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 127191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void **ctxs, 1288c6c5593SMatthew G. Knepley PetscScalar values[]) 1298c6c5593SMatthew G. Knepley { 1308c6c5593SMatthew G. Knepley PetscSection section, sectionAux = NULL; 1314bee2e38SMatthew G. Knepley PetscScalar *u, *u_t = NULL, *u_x, *a = NULL, *a_t = NULL, *a_x = NULL, *bc; 1328c6c5593SMatthew G. Knepley PetscScalar *coefficients = NULL, *coefficientsAux = NULL; 1338c6c5593SMatthew G. Knepley PetscScalar *coefficients_t = NULL, *coefficientsAux_t = NULL; 134191494d9SMatthew G. Knepley const PetscScalar *constants; 1358c6c5593SMatthew G. Knepley PetscReal *x; 136*ef0bb6c7SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL, *Nc; 1374bee2e38SMatthew G. Knepley PetscFEGeom fegeom; 1384bee2e38SMatthew G. Knepley const PetscInt dE = cgeom->dimEmbed; 139*ef0bb6c7SMatthew G. Knepley PetscInt numConstants, Nf, NfIn, NfAux = 0, f, spDim, d, v, inp, tp = 0; 140ca3d3a14SMatthew G. Knepley PetscBool isAffine, transform; 1418c6c5593SMatthew G. Knepley PetscErrorCode ierr; 1428c6c5593SMatthew G. Knepley 1438c6c5593SMatthew G. Knepley PetscFunctionBeginHot; 144a6e0b375SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 145a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponents(ds, &Nc);CHKERRQ(ierr); 146a6e0b375SMatthew G. Knepley ierr = PetscDSGetNumFields(dsIn, &NfIn);CHKERRQ(ierr); 147a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(dsIn, &uOff);CHKERRQ(ierr); 148a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(dsIn, &uOff_x);CHKERRQ(ierr); 149a6e0b375SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(dsIn, &u, &bc /*&u_t*/, &u_x);CHKERRQ(ierr); 150a6e0b375SMatthew G. Knepley ierr = PetscDSGetWorkspace(dsIn, &x, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 151a6e0b375SMatthew G. Knepley ierr = PetscDSGetConstants(dsIn, &numConstants, &constants);CHKERRQ(ierr); 152a6e0b375SMatthew G. Knepley ierr = DMHasBasisTransform(dmIn, &transform);CHKERRQ(ierr); 153a6e0b375SMatthew G. Knepley ierr = DMGetLocalSection(dmIn, §ion);CHKERRQ(ierr); 154a6e0b375SMatthew G. Knepley ierr = DMGetEnclosurePoint(dmIn, dm, encIn, p, &inp);CHKERRQ(ierr); 155a6e0b375SMatthew G. Knepley ierr = DMPlexVecGetClosure(dmIn, section, localU, inp, NULL, &coefficients);CHKERRQ(ierr); 1568c6c5593SMatthew G. Knepley if (dmAux) { 15744171101SMatthew G. Knepley PetscInt subp; 1581ba34526SMatthew G. Knepley 159a6e0b375SMatthew G. Knepley ierr = DMGetEnclosurePoint(dmAux, dm, encAux, p, &subp);CHKERRQ(ierr); 160a6e0b375SMatthew G. Knepley ierr = PetscDSGetNumFields(dsAux, &NfAux);CHKERRQ(ierr); 16192fd8e1eSJed Brown ierr = DMGetLocalSection(dmAux, §ionAux);CHKERRQ(ierr); 162a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(dsAux, &aOff);CHKERRQ(ierr); 163a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x);CHKERRQ(ierr); 164a6e0b375SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(dsAux, &a, NULL /*&a_t*/, &a_x);CHKERRQ(ierr); 1651ba34526SMatthew G. Knepley ierr = DMPlexVecGetClosure(dmAux, sectionAux, localA, subp, NULL, &coefficientsAux);CHKERRQ(ierr); 1668c6c5593SMatthew G. Knepley } 1678c6c5593SMatthew G. Knepley /* Get values for closure */ 1684bee2e38SMatthew G. Knepley isAffine = cgeom->isAffine; 1694bee2e38SMatthew G. Knepley if (isAffine) { 1704bee2e38SMatthew G. Knepley fegeom.v = x; 1714bee2e38SMatthew G. Knepley fegeom.xi = cgeom->xi; 1724bee2e38SMatthew G. Knepley fegeom.J = cgeom->J; 1734bee2e38SMatthew G. Knepley fegeom.invJ = cgeom->invJ; 1744bee2e38SMatthew G. Knepley fegeom.detJ = cgeom->detJ; 1754bee2e38SMatthew G. Knepley } 1768c6c5593SMatthew G. Knepley for (f = 0, v = 0; f < Nf; ++f) { 177c330f8ffSToby Isaac PetscQuadrature allPoints; 178c330f8ffSToby Isaac PetscInt q, dim, numPoints; 179c330f8ffSToby Isaac const PetscReal *points; 180c330f8ffSToby Isaac PetscScalar *pointEval; 181c330f8ffSToby Isaac DM dm; 182c330f8ffSToby Isaac 1838c6c5593SMatthew G. Knepley if (!sp[f]) continue; 1848c6c5593SMatthew G. Knepley ierr = PetscDualSpaceGetDimension(sp[f], &spDim);CHKERRQ(ierr); 185c330f8ffSToby Isaac if (!funcs[f]) { 186be1504a2SMatthew G. Knepley for (d = 0; d < spDim; d++, v++) values[v] = 0.; 187c330f8ffSToby Isaac continue; 188c330f8ffSToby Isaac } 189c330f8ffSToby Isaac ierr = PetscDualSpaceGetDM(sp[f],&dm);CHKERRQ(ierr); 190c330f8ffSToby Isaac ierr = PetscDualSpaceGetAllPoints(sp[f], &allPoints);CHKERRQ(ierr); 191c330f8ffSToby Isaac ierr = PetscQuadratureGetData(allPoints,&dim,NULL,&numPoints,&points,NULL);CHKERRQ(ierr); 192c330f8ffSToby Isaac ierr = DMGetWorkArray(dm,numPoints*Nc[f],MPIU_SCALAR,&pointEval);CHKERRQ(ierr); 1930c898c18SMatthew G. Knepley for (q = 0; q < numPoints; ++q, ++tp) { 194c330f8ffSToby Isaac if (isAffine) { 195*ef0bb6c7SMatthew G. Knepley CoordinatesRefToReal(dE, cgeom->dim, fegeom.xi, cgeom->v, fegeom.J, &points[q*dim], x); 1961c531cf8SMatthew G. Knepley } else { 1974bee2e38SMatthew G. Knepley fegeom.v = &cgeom->v[tp*dE]; 1984bee2e38SMatthew G. Knepley fegeom.J = &cgeom->J[tp*dE*dE]; 1994bee2e38SMatthew G. Knepley fegeom.invJ = &cgeom->invJ[tp*dE*dE]; 2004bee2e38SMatthew G. Knepley fegeom.detJ = &cgeom->detJ[tp]; 2018c6c5593SMatthew G. Knepley } 202*ef0bb6c7SMatthew G. Knepley ierr = PetscFEEvaluateFieldJets_Internal(dsIn, NfIn, 0, tp, T, &fegeom, coefficients, coefficients_t, u, u_x, u_t);CHKERRQ(ierr); 203*ef0bb6c7SMatthew G. Knepley if (dsAux) {ierr = PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, 0, tp, TAux, &fegeom, coefficientsAux, coefficientsAux_t, a, a_x, a_t);CHKERRQ(ierr);} 204a6e0b375SMatthew G. Knepley if (transform) {ierr = DMPlexBasisTransformApplyReal_Internal(dmIn, fegeom.v, PETSC_TRUE, dE, fegeom.v, fegeom.v, dm->transformCtx);CHKERRQ(ierr);} 205a6e0b375SMatthew G. Knepley (*funcs[f])(dE, NfIn, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, a_t, a_x, time, fegeom.v, numConstants, constants, &pointEval[Nc[f]*q]); 2061c531cf8SMatthew G. Knepley } 207c330f8ffSToby Isaac ierr = PetscDualSpaceApplyAll(sp[f], pointEval, &values[v]);CHKERRQ(ierr); 208c330f8ffSToby Isaac ierr = DMRestoreWorkArray(dm,numPoints*Nc[f],MPIU_SCALAR,&pointEval);CHKERRQ(ierr); 209c330f8ffSToby Isaac v += spDim; 2108c6c5593SMatthew G. Knepley } 211a6e0b375SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dmIn, section, localU, inp, NULL, &coefficients);CHKERRQ(ierr); 2128c6c5593SMatthew G. Knepley if (dmAux) {ierr = DMPlexVecRestoreClosure(dmAux, sectionAux, localA, p, NULL, &coefficientsAux);CHKERRQ(ierr);} 2138c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 2148c6c5593SMatthew G. Knepley } 2158c6c5593SMatthew G. Knepley 216a6e0b375SMatthew G. Knepley static PetscErrorCode DMProjectPoint_BdField_Private(DM dm, PetscDS ds, DM dmIn, PetscDS dsIn, DM dmAux, DMEnclosureType encAux, PetscDS dsAux, PetscReal time, Vec localU, Vec localA, PetscFEGeom *fgeom, PetscDualSpace sp[], PetscInt p, 217*ef0bb6c7SMatthew G. Knepley PetscTabulation *T, PetscTabulation *TAux, 218b18799e0SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 219b18799e0SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 220b18799e0SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 221b18799e0SMatthew G. Knepley PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void **ctxs, 222b18799e0SMatthew G. Knepley PetscScalar values[]) 223b18799e0SMatthew G. Knepley { 224b18799e0SMatthew G. Knepley PetscSection section, sectionAux = NULL; 2254bee2e38SMatthew G. Knepley PetscScalar *u, *u_t = NULL, *u_x, *a = NULL, *a_t = NULL, *a_x = NULL, *bc; 226b18799e0SMatthew G. Knepley PetscScalar *coefficients = NULL, *coefficientsAux = NULL; 227b18799e0SMatthew G. Knepley PetscScalar *coefficients_t = NULL, *coefficientsAux_t = NULL; 228b18799e0SMatthew G. Knepley const PetscScalar *constants; 229b18799e0SMatthew G. Knepley PetscReal *x; 230*ef0bb6c7SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL, *Nc; 2319f209ee4SMatthew G. Knepley PetscFEGeom fegeom, cgeom; 2324bee2e38SMatthew G. Knepley const PetscInt dE = fgeom->dimEmbed; 233*ef0bb6c7SMatthew G. Knepley PetscInt numConstants, Nf, NfAux = 0, f, spDim, d, v, tp = 0; 234b18799e0SMatthew G. Knepley PetscBool isAffine; 235b18799e0SMatthew G. Knepley PetscErrorCode ierr; 236b18799e0SMatthew G. Knepley 237b18799e0SMatthew G. Knepley PetscFunctionBeginHot; 238a6e0b375SMatthew G. Knepley if (dm != dmIn) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Not yet upgraded to use different input DM"); 239a6e0b375SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 240a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponents(ds, &Nc);CHKERRQ(ierr); 241a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(ds, &uOff);CHKERRQ(ierr); 242a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(ds, &uOff_x);CHKERRQ(ierr); 243a6e0b375SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(ds, &u, &bc /*&u_t*/, &u_x);CHKERRQ(ierr); 244a6e0b375SMatthew G. Knepley ierr = PetscDSGetWorkspace(ds, &x, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 245a6e0b375SMatthew G. Knepley ierr = PetscDSGetConstants(ds, &numConstants, &constants);CHKERRQ(ierr); 24692fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 247a6e0b375SMatthew G. Knepley ierr = DMPlexVecGetClosure(dmIn, section, localU, p, NULL, &coefficients);CHKERRQ(ierr); 248b18799e0SMatthew G. Knepley if (dmAux) { 249a6e0b375SMatthew G. Knepley PetscInt subp; 250b18799e0SMatthew G. Knepley 251a6e0b375SMatthew G. Knepley ierr = DMGetEnclosurePoint(dmAux, dm, encAux, p, &subp);CHKERRQ(ierr); 252a6e0b375SMatthew G. Knepley ierr = PetscDSGetNumFields(dsAux, &NfAux);CHKERRQ(ierr); 25392fd8e1eSJed Brown ierr = DMGetLocalSection(dmAux, §ionAux);CHKERRQ(ierr); 254a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(dsAux, &aOff);CHKERRQ(ierr); 255a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x);CHKERRQ(ierr); 256a6e0b375SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(dsAux, &a, NULL /*&a_t*/, &a_x);CHKERRQ(ierr); 257b18799e0SMatthew G. Knepley ierr = DMPlexVecGetClosure(dmAux, sectionAux, localA, subp, NULL, &coefficientsAux);CHKERRQ(ierr); 258b18799e0SMatthew G. Knepley } 259b18799e0SMatthew G. Knepley /* Get values for closure */ 2604bee2e38SMatthew G. Knepley isAffine = fgeom->isAffine; 2614dcf62a8SSatish Balay fegeom.n = 0; 2624dcf62a8SSatish Balay fegeom.J = 0; 2634dcf62a8SSatish Balay fegeom.v = 0; 2644dcf62a8SSatish Balay fegeom.xi = 0; 265a6e0b375SMatthew G. Knepley cgeom.dim = fgeom->dim; 266a6e0b375SMatthew G. Knepley cgeom.dimEmbed = fgeom->dimEmbed; 2674bee2e38SMatthew G. Knepley if (isAffine) { 2684bee2e38SMatthew G. Knepley fegeom.v = x; 2694bee2e38SMatthew G. Knepley fegeom.xi = fgeom->xi; 2704bee2e38SMatthew G. Knepley fegeom.J = fgeom->J; 2714bee2e38SMatthew G. Knepley fegeom.invJ = fgeom->invJ; 2724bee2e38SMatthew G. Knepley fegeom.detJ = fgeom->detJ; 2734bee2e38SMatthew G. Knepley fegeom.n = fgeom->n; 2749f209ee4SMatthew G. Knepley 2759f209ee4SMatthew G. Knepley cgeom.J = fgeom->suppJ[0]; 2769f209ee4SMatthew G. Knepley cgeom.invJ = fgeom->suppInvJ[0]; 2779f209ee4SMatthew G. Knepley cgeom.detJ = fgeom->suppDetJ[0]; 2784bee2e38SMatthew G. Knepley } 279b18799e0SMatthew G. Knepley for (f = 0, v = 0; f < Nf; ++f) { 280b18799e0SMatthew G. Knepley PetscQuadrature allPoints; 281b18799e0SMatthew G. Knepley PetscInt q, dim, numPoints; 282b18799e0SMatthew G. Knepley const PetscReal *points; 283b18799e0SMatthew G. Knepley PetscScalar *pointEval; 284b18799e0SMatthew G. Knepley DM dm; 285b18799e0SMatthew G. Knepley 286b18799e0SMatthew G. Knepley if (!sp[f]) continue; 287b18799e0SMatthew G. Knepley ierr = PetscDualSpaceGetDimension(sp[f], &spDim);CHKERRQ(ierr); 288b18799e0SMatthew G. Knepley if (!funcs[f]) { 289b18799e0SMatthew G. Knepley for (d = 0; d < spDim; d++, v++) values[v] = 0.; 290b18799e0SMatthew G. Knepley continue; 291b18799e0SMatthew G. Knepley } 292b18799e0SMatthew G. Knepley ierr = PetscDualSpaceGetDM(sp[f],&dm);CHKERRQ(ierr); 293b18799e0SMatthew G. Knepley ierr = PetscDualSpaceGetAllPoints(sp[f], &allPoints);CHKERRQ(ierr); 294b18799e0SMatthew G. Knepley ierr = PetscQuadratureGetData(allPoints,&dim,NULL,&numPoints,&points,NULL);CHKERRQ(ierr); 295b18799e0SMatthew G. Knepley ierr = DMGetWorkArray(dm,numPoints*Nc[f],MPIU_SCALAR,&pointEval);CHKERRQ(ierr); 296b18799e0SMatthew G. Knepley for (q = 0; q < numPoints; ++q, ++tp) { 297b18799e0SMatthew G. Knepley if (isAffine) { 298*ef0bb6c7SMatthew G. Knepley CoordinatesRefToReal(dE, fgeom->dim, fegeom.xi, fgeom->v, fegeom.J, &points[q*dim], x); 299b18799e0SMatthew G. Knepley } else { 3003fe841f2SMatthew G. Knepley fegeom.v = &fgeom->v[tp*dE]; 3019f209ee4SMatthew G. Knepley fegeom.J = &fgeom->J[tp*dE*dE]; 3029f209ee4SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[tp*dE*dE]; 3034bee2e38SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[tp]; 3044bee2e38SMatthew G. Knepley fegeom.n = &fgeom->n[tp*dE]; 3059f209ee4SMatthew G. Knepley 3069f209ee4SMatthew G. Knepley cgeom.J = &fgeom->suppJ[0][tp*dE*dE]; 3079f209ee4SMatthew G. Knepley cgeom.invJ = &fgeom->suppInvJ[0][tp*dE*dE]; 3089f209ee4SMatthew G. Knepley cgeom.detJ = &fgeom->suppDetJ[0][tp]; 309b18799e0SMatthew G. Knepley } 310a6e0b375SMatthew G. Knepley /* TODO We should use cgeom here, instead of fegeom, however the geometry coming in through fgeom does not have the support cell geometry */ 311*ef0bb6c7SMatthew G. Knepley ierr = PetscFEEvaluateFieldJets_Internal(ds, Nf, 0, tp, T, &cgeom, coefficients, coefficients_t, u, u_x, u_t);CHKERRQ(ierr); 312*ef0bb6c7SMatthew G. Knepley if (dsAux) {ierr = PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, 0, tp, TAux, &cgeom, coefficientsAux, coefficientsAux_t, a, a_x, a_t);CHKERRQ(ierr);} 3134bee2e38SMatthew G. Knepley (*funcs[f])(dE, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, a_t, a_x, time, fegeom.v, fegeom.n, numConstants, constants, &pointEval[Nc[f]*q]); 314b18799e0SMatthew G. Knepley } 315b18799e0SMatthew G. Knepley ierr = PetscDualSpaceApplyAll(sp[f], pointEval, &values[v]);CHKERRQ(ierr); 316b18799e0SMatthew G. Knepley ierr = DMRestoreWorkArray(dm,numPoints*Nc[f],MPIU_SCALAR,&pointEval);CHKERRQ(ierr); 317b18799e0SMatthew G. Knepley v += spDim; 318b18799e0SMatthew G. Knepley } 319a6e0b375SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dmIn, section, localU, p, NULL, &coefficients);CHKERRQ(ierr); 320b18799e0SMatthew G. Knepley if (dmAux) {ierr = DMPlexVecRestoreClosure(dmAux, sectionAux, localA, p, NULL, &coefficientsAux);CHKERRQ(ierr);} 321b18799e0SMatthew G. Knepley PetscFunctionReturn(0); 322b18799e0SMatthew G. Knepley } 323b18799e0SMatthew G. Knepley 324a6e0b375SMatthew G. Knepley static PetscErrorCode DMProjectPoint_Private(DM dm, PetscDS ds, DM dmIn, DMEnclosureType encIn, PetscDS dsIn, DM dmAux, DMEnclosureType encAux, PetscDS dsAux, PetscFEGeom *fegeom, PetscInt effectiveHeight, PetscReal time, Vec localU, Vec localA, PetscBool hasFE, PetscBool hasFV, PetscBool isFE[], 325*ef0bb6c7SMatthew G. Knepley PetscDualSpace sp[], PetscInt p, PetscTabulation *T, PetscTabulation *TAux, 3268c6c5593SMatthew G. Knepley DMBoundaryConditionType type, void (**funcs)(void), void **ctxs, PetscBool fieldActive[], PetscScalar values[]) 3278c6c5593SMatthew G. Knepley { 3288c6c5593SMatthew G. Knepley PetscFVCellGeom fvgeom; 3298c6c5593SMatthew G. Knepley PetscInt dim, dimEmbed; 3308c6c5593SMatthew G. Knepley PetscErrorCode ierr; 3318c6c5593SMatthew G. Knepley 3328c6c5593SMatthew G. Knepley PetscFunctionBeginHot; 3338c6c5593SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 3348c6c5593SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dimEmbed);CHKERRQ(ierr); 3358c6c5593SMatthew G. Knepley if (hasFV) {ierr = DMPlexComputeCellGeometryFVM(dm, p, &fvgeom.volume, fvgeom.centroid, NULL);CHKERRQ(ierr);} 3368c6c5593SMatthew G. Knepley switch (type) { 3378c6c5593SMatthew G. Knepley case DM_BC_ESSENTIAL: 3388c6c5593SMatthew G. Knepley case DM_BC_NATURAL: 339a6e0b375SMatthew G. Knepley ierr = DMProjectPoint_Func_Private(dm, ds, dmIn, dsIn, time, fegeom, &fvgeom, isFE, sp, (PetscErrorCode (**)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *)) funcs, ctxs, values);CHKERRQ(ierr);break; 3408c6c5593SMatthew G. Knepley case DM_BC_ESSENTIAL_FIELD: 3418c6c5593SMatthew G. Knepley case DM_BC_NATURAL_FIELD: 342*ef0bb6c7SMatthew G. Knepley ierr = DMProjectPoint_Field_Private(dm, ds, dmIn, encIn, dsIn, dmAux, encAux, dsAux, time, localU, localA, fegeom, sp, p, T, TAux, 3430c898c18SMatthew G. Knepley (void (**)(PetscInt, PetscInt, PetscInt, 3440c898c18SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 3450c898c18SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 346191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[])) funcs, ctxs, values);CHKERRQ(ierr);break; 347b18799e0SMatthew G. Knepley case DM_BC_ESSENTIAL_BD_FIELD: 348*ef0bb6c7SMatthew G. Knepley ierr = DMProjectPoint_BdField_Private(dm, ds, dmIn, dsIn, dmAux, encAux, dsAux, time, localU, localA, fegeom, sp, p, T, TAux, 349b18799e0SMatthew G. Knepley (void (**)(PetscInt, PetscInt, PetscInt, 350b18799e0SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 351b18799e0SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 352b18799e0SMatthew G. Knepley PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[])) funcs, ctxs, values);CHKERRQ(ierr);break; 3538c6c5593SMatthew G. Knepley default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Unknown boundary condition type: %d", (int) type); 3548c6c5593SMatthew G. Knepley } 3558c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 3568c6c5593SMatthew G. Knepley } 3578c6c5593SMatthew G. Knepley 358df5c1128SToby Isaac static PetscErrorCode PetscDualSpaceGetAllPointsUnion(PetscInt Nf, PetscDualSpace *sp, PetscInt dim, void (**funcs)(void), PetscQuadrature *allPoints) 359df5c1128SToby Isaac { 360df5c1128SToby Isaac PetscReal *points; 361df5c1128SToby Isaac PetscInt f, numPoints; 362df5c1128SToby Isaac PetscErrorCode ierr; 363df5c1128SToby Isaac 364df5c1128SToby Isaac PetscFunctionBegin; 365df5c1128SToby Isaac numPoints = 0; 366df5c1128SToby Isaac for (f = 0; f < Nf; ++f) { 367df5c1128SToby Isaac if (funcs[f]) { 368df5c1128SToby Isaac PetscQuadrature fAllPoints; 369df5c1128SToby Isaac PetscInt fNumPoints; 370df5c1128SToby Isaac 371df5c1128SToby Isaac ierr = PetscDualSpaceGetAllPoints(sp[f],&fAllPoints);CHKERRQ(ierr); 372df5c1128SToby Isaac ierr = PetscQuadratureGetData(fAllPoints, NULL, NULL, &fNumPoints, NULL, NULL);CHKERRQ(ierr); 373df5c1128SToby Isaac numPoints += fNumPoints; 374df5c1128SToby Isaac } 375df5c1128SToby Isaac } 376df5c1128SToby Isaac ierr = PetscMalloc1(dim*numPoints,&points);CHKERRQ(ierr); 377df5c1128SToby Isaac numPoints = 0; 378df5c1128SToby Isaac for (f = 0; f < Nf; ++f) { 379df5c1128SToby Isaac PetscInt spDim; 380df5c1128SToby Isaac 381df5c1128SToby Isaac ierr = PetscDualSpaceGetDimension(sp[f], &spDim);CHKERRQ(ierr); 382df5c1128SToby Isaac if (funcs[f]) { 383df5c1128SToby Isaac PetscQuadrature fAllPoints; 38454ee0cceSMatthew G. Knepley PetscInt qdim, fNumPoints, q; 385df5c1128SToby Isaac const PetscReal *fPoints; 386df5c1128SToby Isaac 387df5c1128SToby Isaac ierr = PetscDualSpaceGetAllPoints(sp[f],&fAllPoints);CHKERRQ(ierr); 38854ee0cceSMatthew G. Knepley ierr = PetscQuadratureGetData(fAllPoints, &qdim, NULL, &fNumPoints, &fPoints, NULL);CHKERRQ(ierr); 38954ee0cceSMatthew G. Knepley if (qdim != dim) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Spatial dimension %D for dual basis does not match input dimension %D", qdim, dim); 390df5c1128SToby Isaac for (q = 0; q < fNumPoints*dim; ++q) points[numPoints*dim+q] = fPoints[q]; 391df5c1128SToby Isaac numPoints += fNumPoints; 392df5c1128SToby Isaac } 393df5c1128SToby Isaac } 394df5c1128SToby Isaac ierr = PetscQuadratureCreate(PETSC_COMM_SELF,allPoints);CHKERRQ(ierr); 395df5c1128SToby Isaac ierr = PetscQuadratureSetData(*allPoints,dim,0,numPoints,points,NULL);CHKERRQ(ierr); 396df5c1128SToby Isaac PetscFunctionReturn(0); 397df5c1128SToby Isaac } 398df5c1128SToby Isaac 399a6e0b375SMatthew G. Knepley static PetscErrorCode DMGetFirstLabelEntry_Private(DM dm, DM odm, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt height, PetscInt *lStart, PetscDS *ds) 400e5e52638SMatthew G. Knepley { 401a6e0b375SMatthew G. Knepley DM plex; 402a6e0b375SMatthew G. Knepley DMEnclosureType enc; 403e5e52638SMatthew G. Knepley DMLabel depthLabel; 404e5e52638SMatthew G. Knepley PetscInt dim, cdepth, ls = -1, i; 405e5e52638SMatthew G. Knepley PetscErrorCode ierr; 406e5e52638SMatthew G. Knepley 407e5e52638SMatthew G. Knepley PetscFunctionBegin; 408e5e52638SMatthew G. Knepley if (lStart) *lStart = -1; 409e5e52638SMatthew G. Knepley if (!label) PetscFunctionReturn(0); 410a6e0b375SMatthew G. Knepley ierr = DMGetEnclosureRelation(dm, odm, &enc);CHKERRQ(ierr); 411e5e52638SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 412a6e0b375SMatthew G. Knepley ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr); 413a6e0b375SMatthew G. Knepley ierr = DMPlexGetDepthLabel(plex, &depthLabel);CHKERRQ(ierr); 414e5e52638SMatthew G. Knepley cdepth = dim - height; 415e5e52638SMatthew G. Knepley for (i = 0; i < numIds; ++i) { 416e5e52638SMatthew G. Knepley IS pointIS; 417e5e52638SMatthew G. Knepley const PetscInt *points; 418a6e0b375SMatthew G. Knepley PetscInt pdepth, point; 419e5e52638SMatthew G. Knepley 420e5e52638SMatthew G. Knepley ierr = DMLabelGetStratumIS(label, ids[i], &pointIS);CHKERRQ(ierr); 421e5e52638SMatthew G. Knepley if (!pointIS) continue; /* No points with that id on this process */ 422e5e52638SMatthew G. Knepley ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 423a6e0b375SMatthew G. Knepley ierr = DMGetEnclosurePoint(dm, odm, enc, points[0], &point);CHKERRQ(ierr); 424a6e0b375SMatthew G. Knepley ierr = DMLabelGetValue(depthLabel, point, &pdepth);CHKERRQ(ierr); 425e5e52638SMatthew G. Knepley if (pdepth == cdepth) { 426a6e0b375SMatthew G. Knepley ls = point; 427a6e0b375SMatthew G. Knepley if (ds) {ierr = DMGetCellDS(dm, ls, ds);CHKERRQ(ierr);} 428e5e52638SMatthew G. Knepley } 429e5e52638SMatthew G. Knepley ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 430e5e52638SMatthew G. Knepley ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 431e5e52638SMatthew G. Knepley if (ls >= 0) break; 432e5e52638SMatthew G. Knepley } 433e5e52638SMatthew G. Knepley if (lStart) *lStart = ls; 434a6e0b375SMatthew G. Knepley ierr = DMDestroy(&plex);CHKERRQ(ierr); 435e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 436e5e52638SMatthew G. Knepley } 437e5e52638SMatthew G. Knepley 4380de51b56SMatthew G. Knepley /* 4390de51b56SMatthew G. Knepley This function iterates over a manifold, and interpolates the input function/field using the basis provided by the DS in our DM 4400de51b56SMatthew G. Knepley 4410de51b56SMatthew G. Knepley There are several different scenarios: 4420de51b56SMatthew G. Knepley 4430de51b56SMatthew G. Knepley 1) Volumetric mesh with volumetric auxiliary data 4440de51b56SMatthew G. Knepley 4450de51b56SMatthew G. Knepley Here minHeight=0 since we loop over cells. 4460de51b56SMatthew G. Knepley 4470de51b56SMatthew G. Knepley 2) Boundary mesh with boundary auxiliary data 4480de51b56SMatthew G. Knepley 4490de51b56SMatthew G. Knepley Here minHeight=1 since we loop over faces. This normally happens since we hang cells off of our boundary meshes to facilitate computation. 4500de51b56SMatthew G. Knepley 4510de51b56SMatthew G. Knepley 3) Volumetric mesh with boundary auxiliary data 4520de51b56SMatthew G. Knepley 4530de51b56SMatthew G. Knepley Here minHeight=1 and auxbd=PETSC_TRUE since we loop over faces and use data only supported on those faces. This is common when imposing Dirichlet boundary conditions. 4540de51b56SMatthew G. Knepley 4550de51b56SMatthew G. Knepley The maxHeight is used to support enforcement of constraints in DMForest. 4560de51b56SMatthew G. Knepley 4570de51b56SMatthew G. Knepley If localU is given and not equal to localX, we call DMPlexInsertBoundaryValues() to complete it. 4580de51b56SMatthew G. Knepley 4590de51b56SMatthew G. Knepley If we are using an input field (DM_BC_ESSENTIAL_FIELD or DM_BC_NATURAL_FIELD), we need to evaluate it at all the quadrature points of the dual basis functionals. 4600de51b56SMatthew G. Knepley - We use effectiveHeight to mean the height above our incoming DS. For example, if the DS is for a submesh then the effective height is zero, whereas if the DS 4610de51b56SMatthew G. Knepley is for the volumetric mesh, but we are iterating over a surface, then the effective height is nonzero. When th effective height is nonzero, we need to extract 4620de51b56SMatthew G. Knepley dual spaces for the boundary from our input spaces. 4630de51b56SMatthew G. Knepley - After extracting all quadrature points, we tabulate the input fields and auxiliary fields on them. 4640de51b56SMatthew G. Knepley 4650de51b56SMatthew G. Knepley We check that the #dof(closure(p)) == #dual basis functionals(p) for a representative p in the iteration 4660de51b56SMatthew G. Knepley 4670de51b56SMatthew G. Knepley If we have a label, we iterate over those points. This will probably break the maxHeight functionality since we do not check the height of those points. 4680de51b56SMatthew G. Knepley */ 46946fa42a0SMatthew G. Knepley static PetscErrorCode DMProjectLocal_Generic_Plex(DM dm, PetscReal time, Vec localU, 4701c531cf8SMatthew G. Knepley PetscInt Ncc, const PetscInt comps[], DMLabel label, PetscInt numIds, const PetscInt ids[], 4718c6c5593SMatthew G. Knepley DMBoundaryConditionType type, void (**funcs)(void), void **ctxs, 4728c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 4738c6c5593SMatthew G. Knepley { 474a6e0b375SMatthew G. Knepley DM plex, dmIn, plexIn, dmAux = NULL, plexAux = NULL, tdm; 475a6e0b375SMatthew G. Knepley DMEnclosureType encIn, encAux; 476a6e0b375SMatthew G. Knepley PetscDS ds = NULL, dsIn = NULL, dsAux = NULL; 477ca3d3a14SMatthew G. Knepley Vec localA = NULL, tv; 47847923291SMatthew G. Knepley PetscSection section; 4798c6c5593SMatthew G. Knepley PetscDualSpace *sp, *cellsp; 480*ef0bb6c7SMatthew G. Knepley PetscTabulation *T = NULL, *TAux = NULL; 4818c6c5593SMatthew G. Knepley PetscInt *Nc; 482a6e0b375SMatthew G. Knepley PetscInt dim, dimEmbed, depth, minHeight, maxHeight, h, Nf, NfIn, NfAux = 0, f; 483ca3d3a14SMatthew G. Knepley PetscBool *isFE, hasFE = PETSC_FALSE, hasFV = PETSC_FALSE, auxBd = PETSC_FALSE, transform; 484c330f8ffSToby Isaac DMField coordField; 485c330f8ffSToby Isaac DMLabel depthLabel; 486c330f8ffSToby Isaac PetscQuadrature allPoints = NULL; 48747923291SMatthew G. Knepley PetscErrorCode ierr; 48847923291SMatthew G. Knepley 48947923291SMatthew G. Knepley PetscFunctionBegin; 490a6e0b375SMatthew G. Knepley if (localU) {ierr = VecGetDM(localU, &dmIn);CHKERRQ(ierr);} 491a6e0b375SMatthew G. Knepley else {dmIn = dm;} 49288aca1feSMatthew G. Knepley ierr = PetscObjectQuery((PetscObject) dm, "dmAux", (PetscObject *) &dmAux);CHKERRQ(ierr); 49388aca1feSMatthew G. Knepley ierr = PetscObjectQuery((PetscObject) dm, "A", (PetscObject *) &localA);CHKERRQ(ierr); 494a6e0b375SMatthew G. Knepley ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr); 495a6e0b375SMatthew G. Knepley ierr = DMConvert(dmIn, DMPLEX, &plexIn);CHKERRQ(ierr); 496a6e0b375SMatthew G. Knepley ierr = DMGetEnclosureRelation(dmIn, dm, &encIn);CHKERRQ(ierr); 497a6e0b375SMatthew G. Knepley ierr = DMGetEnclosureRelation(dmAux, dm, &encAux);CHKERRQ(ierr); 4988c6c5593SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 499a6e0b375SMatthew G. Knepley ierr = DMPlexGetVTKCellHeight(plex, &minHeight);CHKERRQ(ierr); 500ca3d3a14SMatthew G. Knepley ierr = DMGetBasisTransformDM_Internal(dm, &tdm);CHKERRQ(ierr); 501ca3d3a14SMatthew G. Knepley ierr = DMGetBasisTransformVec_Internal(dm, &tv);CHKERRQ(ierr); 502ca3d3a14SMatthew G. Knepley ierr = DMHasBasisTransform(dm, &transform);CHKERRQ(ierr); 5030de51b56SMatthew G. Knepley /* Auxiliary information can only be used with interpolation of field functions */ 504a6e0b375SMatthew G. Knepley if (dmAux) { 505a6e0b375SMatthew G. Knepley ierr = DMConvert(dmAux, DMPLEX, &plexAux);CHKERRQ(ierr); 506a6e0b375SMatthew G. Knepley if (type == DM_BC_ESSENTIAL_FIELD || type == DM_BC_ESSENTIAL_BD_FIELD || type == DM_BC_NATURAL_FIELD) { 507a6e0b375SMatthew G. Knepley if (!localA) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing localA vector"); 508a6e0b375SMatthew G. Knepley if (!minHeight) { 50988aca1feSMatthew G. Knepley DMLabel spmap; 51088aca1feSMatthew G. Knepley 51188aca1feSMatthew G. Knepley /* If dmAux is a surface, then force the projection to take place over a surface */ 512a6e0b375SMatthew G. Knepley ierr = DMPlexGetSubpointMap(plexAux, &spmap);CHKERRQ(ierr); 513e39fcb4eSStefano Zampini if (spmap) { 514a6e0b375SMatthew G. Knepley ierr = DMPlexGetVTKCellHeight(plexAux, &minHeight);CHKERRQ(ierr); 515e39fcb4eSStefano Zampini auxBd = minHeight ? PETSC_TRUE : PETSC_FALSE; 516e39fcb4eSStefano Zampini } 51788aca1feSMatthew G. Knepley } 5180de51b56SMatthew G. Knepley } 519a6e0b375SMatthew G. Knepley } 520a6e0b375SMatthew G. Knepley ierr = DMPlexGetDepth(plex, &depth);CHKERRQ(ierr); 521a6e0b375SMatthew G. Knepley ierr = DMPlexGetDepthLabel(plex, &depthLabel);CHKERRQ(ierr); 522a6e0b375SMatthew G. Knepley ierr = DMPlexGetMaxProjectionHeight(plex, &maxHeight);CHKERRQ(ierr); 5232af58022SMatthew G. Knepley maxHeight = PetscMax(maxHeight, minHeight); 524e39fcb4eSStefano Zampini if (maxHeight < 0 || maxHeight > dim) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Maximum projection height %D not in [0, %D)", maxHeight, dim); 525a6e0b375SMatthew G. Knepley ierr = DMGetFirstLabelEntry_Private(dm, dm, label, numIds, ids, 0, NULL, &ds);CHKERRQ(ierr); 526a6e0b375SMatthew G. Knepley if (!ds) {ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);} 527a6e0b375SMatthew G. Knepley ierr = DMGetFirstLabelEntry_Private(dmIn, dm, label, numIds, ids, 0, NULL, &dsIn);CHKERRQ(ierr); 528a6e0b375SMatthew G. Knepley if (!dsIn) {ierr = DMGetDS(dmIn, &dsIn);CHKERRQ(ierr);} 529a6e0b375SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 530a6e0b375SMatthew G. Knepley ierr = PetscDSGetNumFields(dsIn, &NfIn);CHKERRQ(ierr); 5318c6c5593SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dimEmbed);CHKERRQ(ierr); 53292fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 5330c898c18SMatthew G. Knepley if (dmAux) { 534a6e0b375SMatthew G. Knepley ierr = DMGetDS(dmAux, &dsAux);CHKERRQ(ierr); 535a6e0b375SMatthew G. Knepley ierr = PetscDSGetNumFields(dsAux, &NfAux);CHKERRQ(ierr); 5360c898c18SMatthew G. Knepley } 537a6e0b375SMatthew G. Knepley ierr = PetscDSGetComponents(ds, &Nc);CHKERRQ(ierr); 538496733e2SMatthew G. Knepley ierr = PetscMalloc2(Nf, &isFE, Nf, &sp);CHKERRQ(ierr); 5398c6c5593SMatthew G. Knepley if (maxHeight > 0) {ierr = PetscMalloc1(Nf, &cellsp);CHKERRQ(ierr);} 5408c6c5593SMatthew G. Knepley else {cellsp = sp;} 541a6e0b375SMatthew G. Knepley if (localU && localU != localX) {ierr = DMPlexInsertBoundaryValues(plex, PETSC_TRUE, localU, time, NULL, NULL, NULL);CHKERRQ(ierr);} 5428c6c5593SMatthew G. Knepley /* Get cell dual spaces */ 54347923291SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 54447923291SMatthew G. Knepley PetscObject obj; 54547923291SMatthew G. Knepley PetscClassId id; 54647923291SMatthew G. Knepley 547a6e0b375SMatthew G. Knepley ierr = PetscDSGetDiscretization(ds, f, &obj);CHKERRQ(ierr); 54847923291SMatthew G. Knepley ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 54947923291SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 55047923291SMatthew G. Knepley PetscFE fe = (PetscFE) obj; 55147923291SMatthew G. Knepley 55247923291SMatthew G. Knepley hasFE = PETSC_TRUE; 55347923291SMatthew G. Knepley isFE[f] = PETSC_TRUE; 55447923291SMatthew G. Knepley ierr = PetscFEGetDualSpace(fe, &cellsp[f]);CHKERRQ(ierr); 55547923291SMatthew G. Knepley } else if (id == PETSCFV_CLASSID) { 55647923291SMatthew G. Knepley PetscFV fv = (PetscFV) obj; 55747923291SMatthew G. Knepley 55847923291SMatthew G. Knepley hasFV = PETSC_TRUE; 55947923291SMatthew G. Knepley isFE[f] = PETSC_FALSE; 56047923291SMatthew G. Knepley ierr = PetscFVGetDualSpace(fv, &cellsp[f]);CHKERRQ(ierr); 56147923291SMatthew G. Knepley } else SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", f); 56247923291SMatthew G. Knepley } 563c330f8ffSToby Isaac ierr = DMGetCoordinateField(dm,&coordField);CHKERRQ(ierr); 5640c898c18SMatthew G. Knepley if (type == DM_BC_ESSENTIAL_FIELD || type == DM_BC_NATURAL_FIELD) { 56574fc349aSMatthew G. Knepley PetscInt effectiveHeight = auxBd ? minHeight : 0; 56674fc349aSMatthew G. Knepley PetscFE fem, subfem; 567a6e0b375SMatthew G. Knepley PetscBool isfe; 5684a3e9fdbSToby Isaac const PetscReal *points; 5694a3e9fdbSToby Isaac PetscInt numPoints; 5700c898c18SMatthew G. Knepley 5712af58022SMatthew G. Knepley if (maxHeight > minHeight) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Field projection not supported for face interpolation"); 57254ee0cceSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 57354ee0cceSMatthew G. Knepley if (!effectiveHeight) {sp[f] = cellsp[f];} 57454ee0cceSMatthew G. Knepley else {ierr = PetscDualSpaceGetHeightSubspace(cellsp[f], effectiveHeight, &sp[f]);CHKERRQ(ierr);} 57554ee0cceSMatthew G. Knepley } 57654ee0cceSMatthew G. Knepley ierr = PetscDualSpaceGetAllPointsUnion(Nf,sp,dim-effectiveHeight,funcs,&allPoints);CHKERRQ(ierr); 577c330f8ffSToby Isaac ierr = PetscQuadratureGetData(allPoints,NULL,NULL,&numPoints,&points,NULL);CHKERRQ(ierr); 578*ef0bb6c7SMatthew G. Knepley ierr = PetscMalloc2(NfIn, &T, NfAux, &TAux);CHKERRQ(ierr); 579a6e0b375SMatthew G. Knepley for (f = 0; f < NfIn; ++f) { 580a6e0b375SMatthew G. Knepley ierr = PetscDSIsFE_Internal(dsIn, f, &isfe);CHKERRQ(ierr); 581a6e0b375SMatthew G. Knepley if (!isfe) continue; 582a6e0b375SMatthew G. Knepley ierr = PetscDSGetDiscretization(dsIn, f, (PetscObject *) &fem);CHKERRQ(ierr); 58374fc349aSMatthew G. Knepley if (!effectiveHeight) {subfem = fem;} 58474fc349aSMatthew G. Knepley else {ierr = PetscFEGetHeightSubspace(fem, effectiveHeight, &subfem);CHKERRQ(ierr);} 585*ef0bb6c7SMatthew G. Knepley ierr = PetscFECreateTabulation(subfem, 1, numPoints, points, 1, &T[f]);CHKERRQ(ierr); 5860c898c18SMatthew G. Knepley } 5870c898c18SMatthew G. Knepley for (f = 0; f < NfAux; ++f) { 588a6e0b375SMatthew G. Knepley ierr = PetscDSIsFE_Internal(dsAux, f, &isfe);CHKERRQ(ierr); 589a6e0b375SMatthew G. Knepley if (!isfe) continue; 590a6e0b375SMatthew G. Knepley ierr = PetscDSGetDiscretization(dsAux, f, (PetscObject *) &fem);CHKERRQ(ierr); 59174fc349aSMatthew G. Knepley if (!effectiveHeight || auxBd) {subfem = fem;} 59274fc349aSMatthew G. Knepley else {ierr = PetscFEGetHeightSubspace(fem, effectiveHeight, &subfem);CHKERRQ(ierr);} 593*ef0bb6c7SMatthew G. Knepley ierr = PetscFECreateTabulation(subfem, 1, numPoints, points, 1, &TAux[f]);CHKERRQ(ierr); 5940c898c18SMatthew G. Knepley } 5950c898c18SMatthew G. Knepley } 59647923291SMatthew G. Knepley /* Note: We make no attempt to optimize for height. Higher height things just overwrite the lower height results. */ 5972af58022SMatthew G. Knepley for (h = minHeight; h <= maxHeight; h++) { 59888aca1feSMatthew G. Knepley PetscInt effectiveHeight = h - (auxBd ? 0 : minHeight); 599a6e0b375SMatthew G. Knepley PetscDS dsEff = ds; 6008c6c5593SMatthew G. Knepley PetscScalar *values; 601b7260050SToby Isaac PetscBool *fieldActive; 602b7260050SToby Isaac PetscInt maxDegree; 603e5e52638SMatthew G. Knepley PetscInt pStart, pEnd, p, lStart, spDim, totDim, numValues; 604c330f8ffSToby Isaac IS heightIS; 6058c6c5593SMatthew G. Knepley 606a6e0b375SMatthew G. Knepley /* Note we assume that dm and dmIn share the same topology */ 607a6e0b375SMatthew G. Knepley ierr = DMPlexGetHeightStratum(plex, h, &pStart, &pEnd);CHKERRQ(ierr); 608a6e0b375SMatthew G. Knepley ierr = DMGetFirstLabelEntry_Private(dm, dm, label, numIds, ids, h, &lStart, NULL);CHKERRQ(ierr); 609c330f8ffSToby Isaac ierr = DMLabelGetStratumIS(depthLabel, depth - h, &heightIS);CHKERRQ(ierr); 6108c6c5593SMatthew G. Knepley if (!h) { 6118c6c5593SMatthew G. Knepley PetscInt cEndInterior; 6128c6c5593SMatthew G. Knepley 613485ad865SMatthew G. Knepley ierr = DMPlexGetInteriorCellStratum(dm, NULL, &cEndInterior);CHKERRQ(ierr); 6148c6c5593SMatthew G. Knepley pEnd = cEndInterior < 0 ? pEnd : cEndInterior; 6158c6c5593SMatthew G. Knepley } 616c330f8ffSToby Isaac if (pEnd <= pStart) { 617c330f8ffSToby Isaac ierr = ISDestroy(&heightIS);CHKERRQ(ierr); 618c330f8ffSToby Isaac continue; 619c330f8ffSToby Isaac } 62047923291SMatthew G. Knepley /* Compute totDim, the number of dofs in the closure of a point at this height */ 62147923291SMatthew G. Knepley totDim = 0; 62247923291SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 623bec1f4aaSMatthew G. Knepley if (!effectiveHeight) { 62447923291SMatthew G. Knepley sp[f] = cellsp[f]; 62547923291SMatthew G. Knepley } else { 626bec1f4aaSMatthew G. Knepley ierr = PetscDualSpaceGetHeightSubspace(cellsp[f], effectiveHeight, &sp[f]);CHKERRQ(ierr); 62747923291SMatthew G. Knepley if (!sp[f]) continue; 62847923291SMatthew G. Knepley } 62947923291SMatthew G. Knepley ierr = PetscDualSpaceGetDimension(sp[f], &spDim);CHKERRQ(ierr); 6309c3cf19fSMatthew G. Knepley totDim += spDim; 63147923291SMatthew G. Knepley } 632a6e0b375SMatthew G. Knepley ierr = DMPlexVecGetClosure(plex, section, localX, lStart < 0 ? pStart : lStart, &numValues, NULL);CHKERRQ(ierr); 6338c6c5593SMatthew G. Knepley if (numValues != totDim) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "The section point closure size %d != dual space dimension %d", numValues, totDim); 634c330f8ffSToby Isaac if (!totDim) { 635c330f8ffSToby Isaac ierr = ISDestroy(&heightIS);CHKERRQ(ierr); 636c330f8ffSToby Isaac continue; 637c330f8ffSToby Isaac } 638a6e0b375SMatthew G. Knepley if (effectiveHeight) {ierr = PetscDSGetHeightSubspace(ds, effectiveHeight, &dsEff);CHKERRQ(ierr);} 63947923291SMatthew G. Knepley /* Loop over points at this height */ 64069291d52SBarry Smith ierr = DMGetWorkArray(dm, numValues, MPIU_SCALAR, &values);CHKERRQ(ierr); 64169291d52SBarry Smith ierr = DMGetWorkArray(dm, Nf, MPI_INT, &fieldActive);CHKERRQ(ierr); 6428c6c5593SMatthew G. Knepley for (f = 0; f < Nf; ++f) fieldActive[f] = (funcs[f] && sp[f]) ? PETSC_TRUE : PETSC_FALSE; 6438c6c5593SMatthew G. Knepley if (label) { 6448c6c5593SMatthew G. Knepley PetscInt i; 64547923291SMatthew G. Knepley 64647923291SMatthew G. Knepley for (i = 0; i < numIds; ++i) { 647c330f8ffSToby Isaac IS pointIS, isectIS; 64847923291SMatthew G. Knepley const PetscInt *points; 6498c6c5593SMatthew G. Knepley PetscInt n; 650c330f8ffSToby Isaac PetscFEGeom *fegeom = NULL, *chunkgeom = NULL; 651c330f8ffSToby Isaac PetscQuadrature quad = NULL; 65247923291SMatthew G. Knepley 65347923291SMatthew G. Knepley ierr = DMLabelGetStratumIS(label, ids[i], &pointIS);CHKERRQ(ierr); 65447923291SMatthew G. Knepley if (!pointIS) continue; /* No points with that id on this process */ 655c330f8ffSToby Isaac ierr = ISIntersect(pointIS,heightIS,&isectIS);CHKERRQ(ierr); 656c330f8ffSToby Isaac ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 657c330f8ffSToby Isaac if (!isectIS) continue; 658c330f8ffSToby Isaac ierr = ISGetLocalSize(isectIS, &n);CHKERRQ(ierr); 659c330f8ffSToby Isaac ierr = ISGetIndices(isectIS, &points);CHKERRQ(ierr); 660b7260050SToby Isaac ierr = DMFieldGetDegree(coordField,isectIS,NULL,&maxDegree);CHKERRQ(ierr); 661b7260050SToby Isaac if (maxDegree <= 1) { 662c330f8ffSToby Isaac ierr = DMFieldCreateDefaultQuadrature(coordField,isectIS,&quad);CHKERRQ(ierr); 663c330f8ffSToby Isaac } 664c330f8ffSToby Isaac if (!quad) { 665c330f8ffSToby Isaac if (!h && allPoints) { 666c330f8ffSToby Isaac quad = allPoints; 667c330f8ffSToby Isaac allPoints = NULL; 668c330f8ffSToby Isaac } else { 669c330f8ffSToby Isaac ierr = PetscDualSpaceGetAllPointsUnion(Nf,sp,dim-h,funcs,&quad);CHKERRQ(ierr); 670c330f8ffSToby Isaac } 671c330f8ffSToby Isaac } 672a6e0b375SMatthew G. Knepley ierr = DMFieldCreateFEGeom(coordField,isectIS,quad,(effectiveHeight && h == minHeight)?PETSC_TRUE:PETSC_FALSE,&fegeom);CHKERRQ(ierr); 67347923291SMatthew G. Knepley for (p = 0; p < n; ++p) { 67447923291SMatthew G. Knepley const PetscInt point = points[p]; 67547923291SMatthew G. Knepley 676580bdb30SBarry Smith ierr = PetscArrayzero(values, numValues);CHKERRQ(ierr); 677c330f8ffSToby Isaac ierr = PetscFEGeomGetChunk(fegeom,p,p+1,&chunkgeom);CHKERRQ(ierr); 678*ef0bb6c7SMatthew G. Knepley ierr = DMProjectPoint_Private(dm, dsEff, plexIn, encIn, dsIn, plexAux, encAux, dsAux, chunkgeom, effectiveHeight, time, localU, localA, hasFE, hasFV, isFE, sp, point, T, TAux, type, funcs, ctxs, fieldActive, values); 67947923291SMatthew G. Knepley if (ierr) { 68047923291SMatthew G. Knepley PetscErrorCode ierr2; 68169291d52SBarry Smith ierr2 = DMRestoreWorkArray(dm, numValues, MPIU_SCALAR, &values);CHKERRQ(ierr2); 68269291d52SBarry Smith ierr2 = DMRestoreWorkArray(dm, Nf, MPI_INT, &fieldActive);CHKERRQ(ierr2); 68347923291SMatthew G. Knepley CHKERRQ(ierr); 68447923291SMatthew G. Knepley } 685a6e0b375SMatthew G. Knepley if (transform) {ierr = DMPlexBasisTransformPoint_Internal(plex, tdm, tv, point, fieldActive, PETSC_FALSE, values);CHKERRQ(ierr);} 686a6e0b375SMatthew G. Knepley ierr = DMPlexVecSetFieldClosure_Internal(plex, section, localX, fieldActive, point, Ncc, comps, values, mode);CHKERRQ(ierr); 68747923291SMatthew G. Knepley } 688c330f8ffSToby Isaac ierr = PetscFEGeomRestoreChunk(fegeom,p,p+1,&chunkgeom);CHKERRQ(ierr); 689c330f8ffSToby Isaac ierr = PetscFEGeomDestroy(&fegeom);CHKERRQ(ierr); 690c330f8ffSToby Isaac ierr = PetscQuadratureDestroy(&quad);CHKERRQ(ierr); 691c330f8ffSToby Isaac ierr = ISRestoreIndices(isectIS, &points);CHKERRQ(ierr); 692c330f8ffSToby Isaac ierr = ISDestroy(&isectIS);CHKERRQ(ierr); 69347923291SMatthew G. Knepley } 6948c6c5593SMatthew G. Knepley } else { 695c330f8ffSToby Isaac PetscFEGeom *fegeom = NULL, *chunkgeom = NULL; 696c330f8ffSToby Isaac PetscQuadrature quad = NULL; 697c330f8ffSToby Isaac IS pointIS; 698c330f8ffSToby Isaac 699c330f8ffSToby Isaac ierr = ISCreateStride(PETSC_COMM_SELF,pEnd-pStart,pStart,1,&pointIS);CHKERRQ(ierr); 700b7260050SToby Isaac ierr = DMFieldGetDegree(coordField,pointIS,NULL,&maxDegree);CHKERRQ(ierr); 701b7260050SToby Isaac if (maxDegree <= 1) { 702c330f8ffSToby Isaac ierr = DMFieldCreateDefaultQuadrature(coordField,pointIS,&quad);CHKERRQ(ierr); 703c330f8ffSToby Isaac } 704c330f8ffSToby Isaac if (!quad) { 705c330f8ffSToby Isaac if (!h && allPoints) { 706c330f8ffSToby Isaac quad = allPoints; 707c330f8ffSToby Isaac allPoints = NULL; 708c330f8ffSToby Isaac } else { 709c330f8ffSToby Isaac ierr = PetscDualSpaceGetAllPointsUnion(Nf,sp,dim-h,funcs,&quad);CHKERRQ(ierr); 710c330f8ffSToby Isaac } 711c330f8ffSToby Isaac } 712a6e0b375SMatthew G. Knepley ierr = DMFieldCreateFEGeom(coordField,pointIS,quad,(effectiveHeight && h == minHeight)?PETSC_TRUE:PETSC_FALSE,&fegeom);CHKERRQ(ierr); 7138c6c5593SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 714580bdb30SBarry Smith ierr = PetscArrayzero(values, numValues);CHKERRQ(ierr); 715c330f8ffSToby Isaac ierr = PetscFEGeomGetChunk(fegeom,p-pStart,p-pStart+1,&chunkgeom);CHKERRQ(ierr); 716*ef0bb6c7SMatthew G. Knepley ierr = DMProjectPoint_Private(dm, dsEff, plexIn, encIn, dsIn, plexAux, encAux, dsAux, chunkgeom, effectiveHeight, time, localU, localA, hasFE, hasFV, isFE, sp, p, T, TAux, type, funcs, ctxs, fieldActive, values); 7178c6c5593SMatthew G. Knepley if (ierr) { 7188c6c5593SMatthew G. Knepley PetscErrorCode ierr2; 71969291d52SBarry Smith ierr2 = DMRestoreWorkArray(dm, numValues, MPIU_SCALAR, &values);CHKERRQ(ierr2); 72069291d52SBarry Smith ierr2 = DMRestoreWorkArray(dm, Nf, MPI_INT, &fieldActive);CHKERRQ(ierr2); 7218c6c5593SMatthew G. Knepley CHKERRQ(ierr); 7228c6c5593SMatthew G. Knepley } 723a6e0b375SMatthew G. Knepley if (transform) {ierr = DMPlexBasisTransformPoint_Internal(plex, tdm, tv, p, fieldActive, PETSC_FALSE, values);CHKERRQ(ierr);} 724a6e0b375SMatthew G. Knepley ierr = DMPlexVecSetFieldClosure_Internal(plex, section, localX, fieldActive, p, Ncc, comps, values, mode);CHKERRQ(ierr); 7258c6c5593SMatthew G. Knepley } 726c330f8ffSToby Isaac ierr = PetscFEGeomRestoreChunk(fegeom,p-pStart,pStart-p+1,&chunkgeom);CHKERRQ(ierr); 727c330f8ffSToby Isaac ierr = PetscFEGeomDestroy(&fegeom);CHKERRQ(ierr); 728c330f8ffSToby Isaac ierr = PetscQuadratureDestroy(&quad);CHKERRQ(ierr); 729c330f8ffSToby Isaac ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 7308c6c5593SMatthew G. Knepley } 731c330f8ffSToby Isaac ierr = ISDestroy(&heightIS);CHKERRQ(ierr); 73269291d52SBarry Smith ierr = DMRestoreWorkArray(dm, numValues, MPIU_SCALAR, &values);CHKERRQ(ierr); 73369291d52SBarry Smith ierr = DMRestoreWorkArray(dm, Nf, MPI_INT, &fieldActive);CHKERRQ(ierr); 73447923291SMatthew G. Knepley } 7358c6c5593SMatthew G. Knepley /* Cleanup */ 7360c898c18SMatthew G. Knepley if (type == DM_BC_ESSENTIAL_FIELD || type == DM_BC_NATURAL_FIELD) { 73774fc349aSMatthew G. Knepley PetscInt effectiveHeight = auxBd ? minHeight : 0; 73874fc349aSMatthew G. Knepley PetscFE fem, subfem; 739a6e0b375SMatthew G. Knepley PetscBool isfe; 7400c898c18SMatthew G. Knepley 741a6e0b375SMatthew G. Knepley for (f = 0; f < NfIn; ++f) { 742a6e0b375SMatthew G. Knepley ierr = PetscDSIsFE_Internal(dsIn, f, &isfe);CHKERRQ(ierr); 743a6e0b375SMatthew G. Knepley ierr = PetscDSGetDiscretization(dsIn, f, (PetscObject *) &fem);CHKERRQ(ierr); 74474fc349aSMatthew G. Knepley if (!effectiveHeight) {subfem = fem;} 74574fc349aSMatthew G. Knepley else {ierr = PetscFEGetHeightSubspace(fem, effectiveHeight, &subfem);CHKERRQ(ierr);} 746*ef0bb6c7SMatthew G. Knepley ierr = PetscTabulationDestroy(&T[f]);CHKERRQ(ierr); 7470c898c18SMatthew G. Knepley } 7480c898c18SMatthew G. Knepley for (f = 0; f < NfAux; ++f) { 749a6e0b375SMatthew G. Knepley ierr = PetscDSIsFE_Internal(dsAux, f, &isfe);CHKERRQ(ierr); 750a6e0b375SMatthew G. Knepley ierr = PetscDSGetDiscretization(dsAux, f, (PetscObject *) &fem);CHKERRQ(ierr); 75174fc349aSMatthew G. Knepley if (!effectiveHeight || auxBd) {subfem = fem;} 75274fc349aSMatthew G. Knepley else {ierr = PetscFEGetHeightSubspace(fem, effectiveHeight, &subfem);CHKERRQ(ierr);} 753*ef0bb6c7SMatthew G. Knepley ierr = PetscTabulationDestroy(&TAux[f]);CHKERRQ(ierr); 7540c898c18SMatthew G. Knepley } 755*ef0bb6c7SMatthew G. Knepley ierr = PetscFree2(T, TAux);CHKERRQ(ierr); 7560c898c18SMatthew G. Knepley } 757c330f8ffSToby Isaac ierr = PetscQuadratureDestroy(&allPoints);CHKERRQ(ierr); 758496733e2SMatthew G. Knepley ierr = PetscFree2(isFE, sp);CHKERRQ(ierr); 7598c6c5593SMatthew G. Knepley if (maxHeight > 0) {ierr = PetscFree(cellsp);CHKERRQ(ierr);} 760a6e0b375SMatthew G. Knepley ierr = DMDestroy(&plex);CHKERRQ(ierr); 761a6e0b375SMatthew G. Knepley ierr = DMDestroy(&plexIn);CHKERRQ(ierr); 762a6e0b375SMatthew G. Knepley if (dmAux) {ierr = DMDestroy(&plexAux);CHKERRQ(ierr);} 7638c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 76447923291SMatthew G. Knepley } 7658c6c5593SMatthew G. Knepley 7668c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFunctionLocal_Plex(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX) 7678c6c5593SMatthew G. Knepley { 7688c6c5593SMatthew G. Knepley PetscErrorCode ierr; 7698c6c5593SMatthew G. Knepley 7708c6c5593SMatthew G. Knepley PetscFunctionBegin; 7711c531cf8SMatthew G. Knepley ierr = DMProjectLocal_Generic_Plex(dm, time, localX, 0, NULL, NULL, 0, NULL, DM_BC_ESSENTIAL, (void (**)(void)) funcs, ctxs, mode, localX);CHKERRQ(ierr); 7728c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 7738c6c5593SMatthew G. Knepley } 7748c6c5593SMatthew G. Knepley 7751c531cf8SMatthew G. Knepley PetscErrorCode DMProjectFunctionLabelLocal_Plex(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Ncc, const PetscInt comps[], PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX) 7768c6c5593SMatthew G. Knepley { 7778c6c5593SMatthew G. Knepley PetscErrorCode ierr; 7788c6c5593SMatthew G. Knepley 7798c6c5593SMatthew G. Knepley PetscFunctionBegin; 7801c531cf8SMatthew G. Knepley ierr = DMProjectLocal_Generic_Plex(dm, time, localX, Ncc, comps, label, numIds, ids, DM_BC_ESSENTIAL, (void (**)(void)) funcs, ctxs, mode, localX);CHKERRQ(ierr); 78147923291SMatthew G. Knepley PetscFunctionReturn(0); 78247923291SMatthew G. Knepley } 78347923291SMatthew G. Knepley 7848c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFieldLocal_Plex(DM dm, PetscReal time, Vec localU, 78547923291SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 78647923291SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 78747923291SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 788191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 78947923291SMatthew G. Knepley InsertMode mode, Vec localX) 79047923291SMatthew G. Knepley { 79147923291SMatthew G. Knepley PetscErrorCode ierr; 79247923291SMatthew G. Knepley 79347923291SMatthew G. Knepley PetscFunctionBegin; 7941c531cf8SMatthew G. Knepley ierr = DMProjectLocal_Generic_Plex(dm, time, localU, 0, NULL, NULL, 0, NULL, DM_BC_ESSENTIAL_FIELD, (void (**)(void)) funcs, NULL, mode, localX);CHKERRQ(ierr); 7958c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 79647923291SMatthew G. Knepley } 79747923291SMatthew G. Knepley 7981c531cf8SMatthew G. Knepley PetscErrorCode DMProjectFieldLabelLocal_Plex(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Ncc, const PetscInt comps[], Vec localU, 7998c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 8008c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8018c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 802191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 8038c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 8048c6c5593SMatthew G. Knepley { 8058c6c5593SMatthew G. Knepley PetscErrorCode ierr; 80647923291SMatthew G. Knepley 8078c6c5593SMatthew G. Knepley PetscFunctionBegin; 8081c531cf8SMatthew G. Knepley ierr = DMProjectLocal_Generic_Plex(dm, time, localU, Ncc, comps, label, numIds, ids, DM_BC_ESSENTIAL_FIELD, (void (**)(void)) funcs, NULL, mode, localX);CHKERRQ(ierr); 80947923291SMatthew G. Knepley PetscFunctionReturn(0); 81047923291SMatthew G. Knepley } 811