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 5c330f8ffSToby Isaac static PetscErrorCode DMProjectPoint_Func_Private(DM dm, PetscDS prob, PetscReal time, PetscFEGeom *fegeom, PetscFVCellGeom *fvgeom, PetscBool isFE[], PetscDualSpace sp[], 68c6c5593SMatthew G. Knepley PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, 78c6c5593SMatthew G. Knepley PetscScalar values[]) 847923291SMatthew G. Knepley { 9c330f8ffSToby Isaac PetscInt coordDim, Nf, *Nc, f, totDim, spDim, d, v, tp; 10c330f8ffSToby Isaac PetscBool isAffine; 118c6c5593SMatthew G. Knepley PetscErrorCode ierr; 128c6c5593SMatthew G. Knepley 138c6c5593SMatthew G. Knepley PetscFunctionBeginHot; 14c330f8ffSToby Isaac ierr = DMGetCoordinateDim(dm,&coordDim);CHKERRQ(ierr); 158c6c5593SMatthew G. Knepley ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 16496733e2SMatthew G. Knepley ierr = PetscDSGetComponents(prob, &Nc);CHKERRQ(ierr); 179c3cf19fSMatthew G. Knepley ierr = PetscDSGetTotalDimension(prob, &totDim);CHKERRQ(ierr); 188c6c5593SMatthew G. Knepley /* Get values for closure */ 19c330f8ffSToby Isaac isAffine = fegeom->isAffine; 20c330f8ffSToby Isaac for (f = 0, v = 0, tp = 0; f < Nf; ++f) { 218c6c5593SMatthew G. Knepley void * const ctx = ctxs ? ctxs[f] : NULL; 228c6c5593SMatthew G. Knepley 238c6c5593SMatthew G. Knepley if (!sp[f]) continue; 248c6c5593SMatthew G. Knepley ierr = PetscDualSpaceGetDimension(sp[f], &spDim);CHKERRQ(ierr); 258c6c5593SMatthew G. Knepley if (funcs[f]) { 26c330f8ffSToby Isaac if (isFE[f]) { 27c330f8ffSToby Isaac PetscQuadrature allPoints; 28c330f8ffSToby Isaac PetscInt q, dim, numPoints; 29c330f8ffSToby Isaac const PetscReal *points; 30c330f8ffSToby Isaac PetscScalar *pointEval; 31c330f8ffSToby Isaac PetscReal *x; 32c330f8ffSToby Isaac DM dm; 33c330f8ffSToby Isaac 34c330f8ffSToby Isaac ierr = PetscDualSpaceGetDM(sp[f],&dm);CHKERRQ(ierr); 35c330f8ffSToby Isaac ierr = PetscDualSpaceGetAllPoints(sp[f], &allPoints);CHKERRQ(ierr); 36c330f8ffSToby Isaac ierr = PetscQuadratureGetData(allPoints,&dim,NULL,&numPoints,&points,NULL);CHKERRQ(ierr); 37c330f8ffSToby Isaac ierr = PetscDualSpaceGetDM(sp[f],&dm);CHKERRQ(ierr); 38c330f8ffSToby Isaac ierr = DMGetWorkArray(dm,numPoints*Nc[f],MPIU_SCALAR,&pointEval);CHKERRQ(ierr); 39c330f8ffSToby Isaac ierr = DMGetWorkArray(dm,coordDim,MPIU_REAL,&x);CHKERRQ(ierr); 40c330f8ffSToby Isaac for (q = 0; q < numPoints; q++, tp++) { 41c330f8ffSToby Isaac const PetscReal *v0; 42c330f8ffSToby Isaac 43c330f8ffSToby Isaac if (isAffine) { 44c330f8ffSToby Isaac CoordinatesRefToReal(coordDim, fegeom->dim, fegeom->xi, fegeom->v, fegeom->J, &points[q*dim], x); 45c330f8ffSToby Isaac v0 = x; 468c6c5593SMatthew G. Knepley } else { 47c330f8ffSToby Isaac v0 = &fegeom->v[tp*coordDim]; 488c6c5593SMatthew G. Knepley } 49c330f8ffSToby Isaac ierr = (*funcs[f])(coordDim,time,v0, Nc[f], &pointEval[Nc[f]*q], ctx);CHKERRQ(ierr); 50c330f8ffSToby Isaac } 51c330f8ffSToby Isaac ierr = PetscDualSpaceApplyAll(sp[f], pointEval, &values[v]);CHKERRQ(ierr); 52c330f8ffSToby Isaac ierr = DMRestoreWorkArray(dm,coordDim,MPIU_REAL,&x);CHKERRQ(ierr); 53c330f8ffSToby Isaac ierr = DMRestoreWorkArray(dm,numPoints*Nc[f],MPIU_SCALAR,&pointEval);CHKERRQ(ierr); 54c330f8ffSToby Isaac v += spDim; 55c330f8ffSToby Isaac } else { 56c330f8ffSToby Isaac for (d = 0; d < spDim; ++d, ++v) { 57c330f8ffSToby Isaac ierr = PetscDualSpaceApplyFVM(sp[f], d, time, fvgeom, Nc[f], funcs[f], ctx, &values[v]);CHKERRQ(ierr); 58c330f8ffSToby Isaac } 59c330f8ffSToby Isaac } 60c330f8ffSToby Isaac } else { 61c330f8ffSToby Isaac for (d = 0; d < spDim; d++, v++) {values[v] = 0.0;} 628c6c5593SMatthew G. Knepley } 639c3cf19fSMatthew G. Knepley } 648c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 658c6c5593SMatthew G. Knepley } 668c6c5593SMatthew G. Knepley 67c330f8ffSToby Isaac static PetscErrorCode DMProjectPoint_Field_Private(DM dm, PetscDS prob, DM dmAux, PetscDS probAux, PetscReal time, Vec localU, Vec localA, PetscFEGeom *fegeom, PetscDualSpace sp[], PetscInt p, PetscInt Ncc, const PetscInt comps[], 680c898c18SMatthew G. Knepley PetscReal **basisTab, PetscReal **basisDerTab, PetscReal **basisTabAux, PetscReal **basisDerTabAux, 698c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 708c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 718c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 72191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void **ctxs, 738c6c5593SMatthew G. Knepley PetscScalar values[]) 748c6c5593SMatthew G. Knepley { 758c6c5593SMatthew G. Knepley PetscSection section, sectionAux = NULL; 769c3cf19fSMatthew G. Knepley PetscScalar *u, *u_t = NULL, *u_x, *a = NULL, *a_t = NULL, *a_x = NULL, *refSpaceDer, *refSpaceDerAux = NULL, *bc; 778c6c5593SMatthew G. Knepley PetscScalar *coefficients = NULL, *coefficientsAux = NULL; 788c6c5593SMatthew G. Knepley PetscScalar *coefficients_t = NULL, *coefficientsAux_t = NULL; 79191494d9SMatthew G. Knepley const PetscScalar *constants; 808c6c5593SMatthew G. Knepley PetscReal *x; 81496733e2SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL, *Nb, *Nc, *NbAux = NULL, *NcAux = NULL; 82c330f8ffSToby Isaac const PetscInt dE = fegeom->dimEmbed; 83c330f8ffSToby Isaac PetscInt dimAux = 0, numConstants, Nf, NfAux = 0, f, spDim, d, v, tp = 0; 84c330f8ffSToby Isaac PetscBool isAffine; 858c6c5593SMatthew G. Knepley PetscErrorCode ierr; 868c6c5593SMatthew G. Knepley 878c6c5593SMatthew G. Knepley PetscFunctionBeginHot; 888c6c5593SMatthew G. Knepley ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 89496733e2SMatthew G. Knepley ierr = PetscDSGetDimensions(prob, &Nb);CHKERRQ(ierr); 90496733e2SMatthew G. Knepley ierr = PetscDSGetComponents(prob, &Nc);CHKERRQ(ierr); 918c6c5593SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(prob, &uOff);CHKERRQ(ierr); 928c6c5593SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(prob, &uOff_x);CHKERRQ(ierr); 939c3cf19fSMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(prob, &u, &bc /*&u_t*/, &u_x);CHKERRQ(ierr); 94496733e2SMatthew G. Knepley ierr = PetscDSGetRefCoordArrays(prob, &x, &refSpaceDer);CHKERRQ(ierr); 95191494d9SMatthew G. Knepley ierr = PetscDSGetConstants(prob, &numConstants, &constants);CHKERRQ(ierr); 96e87a4003SBarry Smith ierr = DMGetSection(dm, §ion);CHKERRQ(ierr); 97496733e2SMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, section, localU, p, NULL, &coefficients);CHKERRQ(ierr); 988c6c5593SMatthew G. Knepley if (dmAux) { 99dcc01f9aSMatthew G. Knepley DMLabel spmap; 100dcc01f9aSMatthew G. Knepley PetscInt subp = p; 1011ba34526SMatthew G. Knepley 102dcc01f9aSMatthew G. Knepley /* If dm is a submesh, do not get subpoint */ 103dcc01f9aSMatthew G. Knepley ierr = DMPlexGetSubpointMap(dm, &spmap);CHKERRQ(ierr); 104e39fcb4eSStefano Zampini if (!spmap) { 105e39fcb4eSStefano Zampini PetscInt h; 106e39fcb4eSStefano Zampini ierr = DMPlexGetVTKCellHeight(dmAux, &h);CHKERRQ(ierr); 107e39fcb4eSStefano Zampini ierr = DMPlexGetSubpointMap(dmAux, &spmap);CHKERRQ(ierr); 108e39fcb4eSStefano Zampini if (spmap && !h) { ierr = DMLabelGetValue(spmap, p, &subp);CHKERRQ(ierr); } 109e39fcb4eSStefano Zampini else { ierr = DMPlexGetSubpoint(dmAux, p, &subp);CHKERRQ(ierr); } 110e39fcb4eSStefano Zampini } 1111ba34526SMatthew G. Knepley ierr = PetscDSGetSpatialDimension(probAux, &dimAux);CHKERRQ(ierr); 1128c6c5593SMatthew G. Knepley ierr = PetscDSGetNumFields(probAux, &NfAux);CHKERRQ(ierr); 113496733e2SMatthew G. Knepley ierr = PetscDSGetDimensions(probAux, &NbAux);CHKERRQ(ierr); 114496733e2SMatthew G. Knepley ierr = PetscDSGetComponents(probAux, &NcAux);CHKERRQ(ierr); 115e87a4003SBarry Smith ierr = DMGetSection(dmAux, §ionAux);CHKERRQ(ierr); 1168c6c5593SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(probAux, &aOff);CHKERRQ(ierr); 1178c6c5593SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(probAux, &aOff_x);CHKERRQ(ierr); 11811d189daSMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(probAux, &a, NULL /*&a_t*/, &a_x);CHKERRQ(ierr); 119496733e2SMatthew G. Knepley ierr = PetscDSGetRefCoordArrays(probAux, NULL, &refSpaceDerAux);CHKERRQ(ierr); 1201ba34526SMatthew G. Knepley ierr = DMPlexVecGetClosure(dmAux, sectionAux, localA, subp, NULL, &coefficientsAux);CHKERRQ(ierr); 1218c6c5593SMatthew G. Knepley } 1228c6c5593SMatthew G. Knepley /* Get values for closure */ 123c330f8ffSToby Isaac isAffine = fegeom->isAffine; 1248c6c5593SMatthew G. Knepley for (f = 0, v = 0; f < Nf; ++f) { 125c330f8ffSToby Isaac PetscQuadrature allPoints; 126c330f8ffSToby Isaac PetscInt q, dim, numPoints; 127c330f8ffSToby Isaac const PetscReal *points; 128c330f8ffSToby Isaac PetscScalar *pointEval; 129c330f8ffSToby Isaac DM dm; 130c330f8ffSToby Isaac 1318c6c5593SMatthew G. Knepley if (!sp[f]) continue; 1328c6c5593SMatthew G. Knepley ierr = PetscDualSpaceGetDimension(sp[f], &spDim);CHKERRQ(ierr); 133c330f8ffSToby Isaac if (!funcs[f]) { 134be1504a2SMatthew G. Knepley for (d = 0; d < spDim; d++, v++) values[v] = 0.; 135c330f8ffSToby Isaac continue; 136c330f8ffSToby Isaac } 137c330f8ffSToby Isaac ierr = PetscDualSpaceGetDM(sp[f],&dm);CHKERRQ(ierr); 138c330f8ffSToby Isaac ierr = PetscDualSpaceGetAllPoints(sp[f], &allPoints);CHKERRQ(ierr); 139c330f8ffSToby Isaac ierr = PetscQuadratureGetData(allPoints,&dim,NULL,&numPoints,&points,NULL);CHKERRQ(ierr); 140c330f8ffSToby Isaac ierr = DMGetWorkArray(dm,numPoints*Nc[f],MPIU_SCALAR,&pointEval);CHKERRQ(ierr); 1410c898c18SMatthew G. Knepley for (q = 0; q < numPoints; ++q, ++tp) { 142c330f8ffSToby Isaac const PetscReal *v0; 143c330f8ffSToby Isaac const PetscReal *invJ; 144c330f8ffSToby Isaac 145c330f8ffSToby Isaac if (isAffine) { 146be1504a2SMatthew G. Knepley CoordinatesRefToReal(dE, dim, fegeom->xi, fegeom->v, fegeom->J, &points[q*dim], x); 147c330f8ffSToby Isaac v0 = x; 148c330f8ffSToby Isaac invJ = fegeom->invJ; 1491c531cf8SMatthew G. Knepley } else { 150c330f8ffSToby Isaac v0 = &fegeom->v[tp*dE]; 151c330f8ffSToby Isaac invJ = &fegeom->invJ[tp*dE*dE]; 1528c6c5593SMatthew G. Knepley } 153c330f8ffSToby Isaac EvaluateFieldJets(dim, Nf, Nb, Nc, tp, basisTab, basisDerTab, refSpaceDer, invJ, coefficients, coefficients_t, u, u_x, u_t); 154e39fcb4eSStefano Zampini if (probAux) EvaluateFieldJets(dimAux, NfAux, NbAux, NcAux, tp, basisTabAux, basisDerTabAux, refSpaceDerAux, invJ, coefficientsAux, coefficientsAux_t, a, a_x, a_t); 155be1504a2SMatthew G. Knepley (*funcs[f])(dE, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, a_t, a_x, time, v0, numConstants, constants, &pointEval[Nc[f]*q]); 1561c531cf8SMatthew G. Knepley } 157c330f8ffSToby Isaac ierr = PetscDualSpaceApplyAll(sp[f], pointEval, &values[v]);CHKERRQ(ierr); 158c330f8ffSToby Isaac ierr = DMRestoreWorkArray(dm,numPoints*Nc[f],MPIU_SCALAR,&pointEval);CHKERRQ(ierr); 159c330f8ffSToby Isaac v += spDim; 1608c6c5593SMatthew G. Knepley } 1618c6c5593SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, section, localU, p, NULL, &coefficients);CHKERRQ(ierr); 1628c6c5593SMatthew G. Knepley if (dmAux) {ierr = DMPlexVecRestoreClosure(dmAux, sectionAux, localA, p, NULL, &coefficientsAux);CHKERRQ(ierr);} 1638c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 1648c6c5593SMatthew G. Knepley } 1658c6c5593SMatthew G. Knepley 166c330f8ffSToby Isaac static PetscErrorCode DMProjectPoint_Private(DM dm, PetscDS prob, PetscFEGeom *fegeom, DM dmAux, PetscDS probAux, PetscInt effectiveHeight, PetscReal time, Vec localU, Vec localA, PetscBool hasFE, PetscBool hasFV, PetscBool isFE[], 1671c531cf8SMatthew G. Knepley PetscDualSpace sp[], PetscInt p, PetscInt Ncc, const PetscInt comps[], 1681c531cf8SMatthew G. Knepley PetscReal **basisTab, PetscReal **basisDerTab, PetscReal **basisTabAux, PetscReal **basisDerTabAux, 1698c6c5593SMatthew G. Knepley DMBoundaryConditionType type, void (**funcs)(void), void **ctxs, PetscBool fieldActive[], PetscScalar values[]) 1708c6c5593SMatthew G. Knepley { 1718c6c5593SMatthew G. Knepley PetscFVCellGeom fvgeom; 1728c6c5593SMatthew G. Knepley PetscInt dim, dimEmbed; 1738c6c5593SMatthew G. Knepley PetscErrorCode ierr; 1748c6c5593SMatthew G. Knepley 1758c6c5593SMatthew G. Knepley PetscFunctionBeginHot; 1768c6c5593SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 1778c6c5593SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dimEmbed);CHKERRQ(ierr); 1788c6c5593SMatthew G. Knepley if (hasFV) {ierr = DMPlexComputeCellGeometryFVM(dm, p, &fvgeom.volume, fvgeom.centroid, NULL);CHKERRQ(ierr);} 1798c6c5593SMatthew G. Knepley switch (type) { 1808c6c5593SMatthew G. Knepley case DM_BC_ESSENTIAL: 1818c6c5593SMatthew G. Knepley case DM_BC_NATURAL: 182c330f8ffSToby Isaac ierr = DMProjectPoint_Func_Private(dm, prob, time, fegeom, &fvgeom, isFE, sp, (PetscErrorCode (**)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *)) funcs, ctxs, values);CHKERRQ(ierr);break; 1838c6c5593SMatthew G. Knepley case DM_BC_ESSENTIAL_FIELD: 1848c6c5593SMatthew G. Knepley case DM_BC_NATURAL_FIELD: 185c330f8ffSToby Isaac ierr = DMProjectPoint_Field_Private(dm, prob, dmAux, probAux, time, localU, localA, fegeom, sp, p, Ncc, comps, 1860c898c18SMatthew G. Knepley basisTab, basisDerTab, basisTabAux, basisDerTabAux, 1870c898c18SMatthew G. Knepley (void (**)(PetscInt, PetscInt, PetscInt, 1880c898c18SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 1890c898c18SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 190191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[])) funcs, ctxs, values);CHKERRQ(ierr);break; 1918c6c5593SMatthew G. Knepley default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Unknown boundary condition type: %d", (int) type); 1928c6c5593SMatthew G. Knepley } 1938c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 1948c6c5593SMatthew G. Knepley } 1958c6c5593SMatthew G. Knepley 196df5c1128SToby Isaac static PetscErrorCode PetscDualSpaceGetAllPointsUnion(PetscInt Nf, PetscDualSpace *sp, PetscInt dim, void (**funcs)(void), PetscQuadrature *allPoints) 197df5c1128SToby Isaac { 198df5c1128SToby Isaac PetscReal *points; 199df5c1128SToby Isaac PetscInt f, numPoints; 200df5c1128SToby Isaac PetscErrorCode ierr; 201df5c1128SToby Isaac 202df5c1128SToby Isaac PetscFunctionBegin; 203df5c1128SToby Isaac numPoints = 0; 204df5c1128SToby Isaac for (f = 0; f < Nf; ++f) { 205df5c1128SToby Isaac if (funcs[f]) { 206df5c1128SToby Isaac PetscQuadrature fAllPoints; 207df5c1128SToby Isaac PetscInt fNumPoints; 208df5c1128SToby Isaac 209df5c1128SToby Isaac ierr = PetscDualSpaceGetAllPoints(sp[f],&fAllPoints);CHKERRQ(ierr); 210df5c1128SToby Isaac ierr = PetscQuadratureGetData(fAllPoints, NULL, NULL, &fNumPoints, NULL, NULL);CHKERRQ(ierr); 211df5c1128SToby Isaac numPoints += fNumPoints; 212df5c1128SToby Isaac } 213df5c1128SToby Isaac } 214df5c1128SToby Isaac ierr = PetscMalloc1(dim*numPoints,&points);CHKERRQ(ierr); 215df5c1128SToby Isaac numPoints = 0; 216df5c1128SToby Isaac for (f = 0; f < Nf; ++f) { 217df5c1128SToby Isaac PetscInt spDim; 218df5c1128SToby Isaac 219df5c1128SToby Isaac ierr = PetscDualSpaceGetDimension(sp[f], &spDim);CHKERRQ(ierr); 220df5c1128SToby Isaac if (funcs[f]) { 221df5c1128SToby Isaac PetscQuadrature fAllPoints; 22254ee0cceSMatthew G. Knepley PetscInt qdim, fNumPoints, q; 223df5c1128SToby Isaac const PetscReal *fPoints; 224df5c1128SToby Isaac 225df5c1128SToby Isaac ierr = PetscDualSpaceGetAllPoints(sp[f],&fAllPoints);CHKERRQ(ierr); 22654ee0cceSMatthew G. Knepley ierr = PetscQuadratureGetData(fAllPoints, &qdim, NULL, &fNumPoints, &fPoints, NULL);CHKERRQ(ierr); 22754ee0cceSMatthew 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); 228df5c1128SToby Isaac for (q = 0; q < fNumPoints*dim; ++q) points[numPoints*dim+q] = fPoints[q]; 229df5c1128SToby Isaac numPoints += fNumPoints; 230df5c1128SToby Isaac } 231df5c1128SToby Isaac } 232df5c1128SToby Isaac ierr = PetscQuadratureCreate(PETSC_COMM_SELF,allPoints);CHKERRQ(ierr); 233df5c1128SToby Isaac ierr = PetscQuadratureSetData(*allPoints,dim,0,numPoints,points,NULL);CHKERRQ(ierr); 234df5c1128SToby Isaac PetscFunctionReturn(0); 235df5c1128SToby Isaac } 236df5c1128SToby Isaac 237*e5e52638SMatthew G. Knepley static PetscErrorCode DMGetFirstLabelEntry_Private(DM dm, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt height, PetscInt *lStart, PetscDS *prob) 238*e5e52638SMatthew G. Knepley { 239*e5e52638SMatthew G. Knepley DMLabel depthLabel; 240*e5e52638SMatthew G. Knepley PetscInt dim, cdepth, ls = -1, i; 241*e5e52638SMatthew G. Knepley PetscErrorCode ierr; 242*e5e52638SMatthew G. Knepley 243*e5e52638SMatthew G. Knepley PetscFunctionBegin; 244*e5e52638SMatthew G. Knepley if (lStart) *lStart = -1; 245*e5e52638SMatthew G. Knepley if (!label) PetscFunctionReturn(0); 246*e5e52638SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 247*e5e52638SMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &depthLabel);CHKERRQ(ierr); 248*e5e52638SMatthew G. Knepley cdepth = dim - height; 249*e5e52638SMatthew G. Knepley for (i = 0; i < numIds; ++i) { 250*e5e52638SMatthew G. Knepley IS pointIS; 251*e5e52638SMatthew G. Knepley const PetscInt *points; 252*e5e52638SMatthew G. Knepley PetscInt pdepth; 253*e5e52638SMatthew G. Knepley 254*e5e52638SMatthew G. Knepley ierr = DMLabelGetStratumIS(label, ids[i], &pointIS);CHKERRQ(ierr); 255*e5e52638SMatthew G. Knepley if (!pointIS) continue; /* No points with that id on this process */ 256*e5e52638SMatthew G. Knepley ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 257*e5e52638SMatthew G. Knepley ierr = DMLabelGetValue(depthLabel, points[0], &pdepth);CHKERRQ(ierr); 258*e5e52638SMatthew G. Knepley if (pdepth == cdepth) { 259*e5e52638SMatthew G. Knepley ls = points[0]; 260*e5e52638SMatthew G. Knepley if (prob) {ierr = DMGetCellDS(dm, ls, prob);CHKERRQ(ierr);} 261*e5e52638SMatthew G. Knepley } 262*e5e52638SMatthew G. Knepley ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 263*e5e52638SMatthew G. Knepley ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 264*e5e52638SMatthew G. Knepley if (ls >= 0) break; 265*e5e52638SMatthew G. Knepley } 266*e5e52638SMatthew G. Knepley if (lStart) *lStart = ls; 267*e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 268*e5e52638SMatthew G. Knepley } 269*e5e52638SMatthew G. Knepley 2700de51b56SMatthew G. Knepley /* 2710de51b56SMatthew G. Knepley This function iterates over a manifold, and interpolates the input function/field using the basis provided by the DS in our DM 2720de51b56SMatthew G. Knepley 2730de51b56SMatthew G. Knepley There are several different scenarios: 2740de51b56SMatthew G. Knepley 2750de51b56SMatthew G. Knepley 1) Volumetric mesh with volumetric auxiliary data 2760de51b56SMatthew G. Knepley 2770de51b56SMatthew G. Knepley Here minHeight=0 since we loop over cells. 2780de51b56SMatthew G. Knepley 2790de51b56SMatthew G. Knepley 2) Boundary mesh with boundary auxiliary data 2800de51b56SMatthew G. Knepley 2810de51b56SMatthew 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. 2820de51b56SMatthew G. Knepley 2830de51b56SMatthew G. Knepley 3) Volumetric mesh with boundary auxiliary data 2840de51b56SMatthew G. Knepley 2850de51b56SMatthew 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. 2860de51b56SMatthew G. Knepley 2870de51b56SMatthew G. Knepley The maxHeight is used to support enforcement of constraints in DMForest. 2880de51b56SMatthew G. Knepley 2890de51b56SMatthew G. Knepley If localU is given and not equal to localX, we call DMPlexInsertBoundaryValues() to complete it. 2900de51b56SMatthew G. Knepley 2910de51b56SMatthew 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. 2920de51b56SMatthew 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 2930de51b56SMatthew 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 2940de51b56SMatthew G. Knepley dual spaces for the boundary from our input spaces. 2950de51b56SMatthew G. Knepley - After extracting all quadrature points, we tabulate the input fields and auxiliary fields on them. 2960de51b56SMatthew G. Knepley 2970de51b56SMatthew G. Knepley We check that the #dof(closure(p)) == #dual basis functionals(p) for a representative p in the iteration 2980de51b56SMatthew G. Knepley 2990de51b56SMatthew 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. 3000de51b56SMatthew G. Knepley */ 30146fa42a0SMatthew G. Knepley static PetscErrorCode DMProjectLocal_Generic_Plex(DM dm, PetscReal time, Vec localU, 3021c531cf8SMatthew G. Knepley PetscInt Ncc, const PetscInt comps[], DMLabel label, PetscInt numIds, const PetscInt ids[], 3038c6c5593SMatthew G. Knepley DMBoundaryConditionType type, void (**funcs)(void), void **ctxs, 3048c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 3058c6c5593SMatthew G. Knepley { 3068c6c5593SMatthew G. Knepley DM dmAux = NULL; 307*e5e52638SMatthew G. Knepley PetscDS prob = NULL, probAux = NULL; 3088c6c5593SMatthew G. Knepley Vec localA = NULL; 30947923291SMatthew G. Knepley PetscSection section; 3108c6c5593SMatthew G. Knepley PetscDualSpace *sp, *cellsp; 3110c898c18SMatthew G. Knepley PetscReal **basisTab = NULL, **basisDerTab = NULL, **basisTabAux = NULL, **basisDerTabAux = NULL; 3128c6c5593SMatthew G. Knepley PetscInt *Nc; 313c330f8ffSToby Isaac PetscInt dim, dimEmbed, depth, minHeight, maxHeight, h, Nf, NfAux = 0, f; 31488aca1feSMatthew G. Knepley PetscBool *isFE, hasFE = PETSC_FALSE, hasFV = PETSC_FALSE, auxBd = PETSC_FALSE; 315c330f8ffSToby Isaac DMField coordField; 316c330f8ffSToby Isaac DMLabel depthLabel; 317c330f8ffSToby Isaac PetscQuadrature allPoints = NULL; 31847923291SMatthew G. Knepley PetscErrorCode ierr; 31947923291SMatthew G. Knepley 32047923291SMatthew G. Knepley PetscFunctionBegin; 32188aca1feSMatthew G. Knepley ierr = PetscObjectQuery((PetscObject) dm, "dmAux", (PetscObject *) &dmAux);CHKERRQ(ierr); 32288aca1feSMatthew G. Knepley ierr = PetscObjectQuery((PetscObject) dm, "A", (PetscObject *) &localA);CHKERRQ(ierr); 3238c6c5593SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 3242af58022SMatthew G. Knepley ierr = DMPlexGetVTKCellHeight(dm, &minHeight);CHKERRQ(ierr); 3250de51b56SMatthew G. Knepley /* Auxiliary information can only be used with interpolation of field functions */ 3260de51b56SMatthew G. Knepley if (type == DM_BC_ESSENTIAL_FIELD || type == DM_BC_NATURAL_FIELD) { 327e39fcb4eSStefano Zampini if (dmAux && !localA) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing localA vector"); 32888aca1feSMatthew G. Knepley if (!minHeight && dmAux) { 32988aca1feSMatthew G. Knepley DMLabel spmap; 33088aca1feSMatthew G. Knepley 33188aca1feSMatthew G. Knepley /* If dmAux is a surface, then force the projection to take place over a surface */ 33288aca1feSMatthew G. Knepley ierr = DMPlexGetSubpointMap(dmAux, &spmap);CHKERRQ(ierr); 333e39fcb4eSStefano Zampini if (spmap) { 334e39fcb4eSStefano Zampini ierr = DMPlexGetVTKCellHeight(dmAux, &minHeight);CHKERRQ(ierr); 335e39fcb4eSStefano Zampini auxBd = minHeight ? PETSC_TRUE : PETSC_FALSE; 336e39fcb4eSStefano Zampini } 33788aca1feSMatthew G. Knepley } 3380de51b56SMatthew G. Knepley } 339*e5e52638SMatthew G. Knepley ierr = DMPlexGetDepth(dm,&depth);CHKERRQ(ierr); 340*e5e52638SMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm,&depthLabel);CHKERRQ(ierr); 3418c6c5593SMatthew G. Knepley ierr = DMPlexGetMaxProjectionHeight(dm, &maxHeight);CHKERRQ(ierr); 3422af58022SMatthew G. Knepley maxHeight = PetscMax(maxHeight, minHeight); 343e39fcb4eSStefano Zampini if (maxHeight < 0 || maxHeight > dim) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Maximum projection height %D not in [0, %D)", maxHeight, dim); 344*e5e52638SMatthew G. Knepley ierr = DMGetFirstLabelEntry_Private(dm, label, numIds, ids, 0, NULL, &prob);CHKERRQ(ierr); 345*e5e52638SMatthew G. Knepley if (!prob) {ierr = DMGetDS(dm, &prob);CHKERRQ(ierr);} 346*e5e52638SMatthew G. Knepley ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 3478c6c5593SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dimEmbed);CHKERRQ(ierr); 348e87a4003SBarry Smith ierr = DMGetSection(dm, §ion);CHKERRQ(ierr); 3490c898c18SMatthew G. Knepley if (dmAux) { 3500c898c18SMatthew G. Knepley ierr = DMGetDS(dmAux, &probAux);CHKERRQ(ierr); 3510c898c18SMatthew G. Knepley ierr = PetscDSGetNumFields(probAux, &NfAux);CHKERRQ(ierr); 3520c898c18SMatthew G. Knepley } 353496733e2SMatthew G. Knepley ierr = PetscDSGetComponents(prob, &Nc);CHKERRQ(ierr); 354496733e2SMatthew G. Knepley ierr = PetscMalloc2(Nf, &isFE, Nf, &sp);CHKERRQ(ierr); 3558c6c5593SMatthew G. Knepley if (maxHeight > 0) {ierr = PetscMalloc1(Nf, &cellsp);CHKERRQ(ierr);} 3568c6c5593SMatthew G. Knepley else {cellsp = sp;} 3578c6c5593SMatthew G. Knepley if (localU && localU != localX) {ierr = DMPlexInsertBoundaryValues(dm, PETSC_TRUE, localU, time, NULL, NULL, NULL);CHKERRQ(ierr);} 3588c6c5593SMatthew G. Knepley /* Get cell dual spaces */ 35947923291SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 36047923291SMatthew G. Knepley PetscObject obj; 36147923291SMatthew G. Knepley PetscClassId id; 36247923291SMatthew G. Knepley 363*e5e52638SMatthew G. Knepley ierr = PetscDSGetDiscretization(prob, f, &obj);CHKERRQ(ierr); 36447923291SMatthew G. Knepley ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 36547923291SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 36647923291SMatthew G. Knepley PetscFE fe = (PetscFE) obj; 36747923291SMatthew G. Knepley 36847923291SMatthew G. Knepley hasFE = PETSC_TRUE; 36947923291SMatthew G. Knepley isFE[f] = PETSC_TRUE; 37047923291SMatthew G. Knepley ierr = PetscFEGetDualSpace(fe, &cellsp[f]);CHKERRQ(ierr); 37147923291SMatthew G. Knepley } else if (id == PETSCFV_CLASSID) { 37247923291SMatthew G. Knepley PetscFV fv = (PetscFV) obj; 37347923291SMatthew G. Knepley 37447923291SMatthew G. Knepley hasFV = PETSC_TRUE; 37547923291SMatthew G. Knepley isFE[f] = PETSC_FALSE; 37647923291SMatthew G. Knepley ierr = PetscFVGetDualSpace(fv, &cellsp[f]);CHKERRQ(ierr); 37747923291SMatthew G. Knepley } else SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", f); 37847923291SMatthew G. Knepley } 379c330f8ffSToby Isaac ierr = DMGetCoordinateField(dm,&coordField);CHKERRQ(ierr); 3800c898c18SMatthew G. Knepley if (type == DM_BC_ESSENTIAL_FIELD || type == DM_BC_NATURAL_FIELD) { 38174fc349aSMatthew G. Knepley PetscInt effectiveHeight = auxBd ? minHeight : 0; 38274fc349aSMatthew G. Knepley PetscFE fem, subfem; 3834a3e9fdbSToby Isaac const PetscReal *points; 3844a3e9fdbSToby Isaac PetscInt numPoints; 3850c898c18SMatthew G. Knepley 3862af58022SMatthew G. Knepley if (maxHeight > minHeight) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Field projection not supported for face interpolation"); 38754ee0cceSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 38854ee0cceSMatthew G. Knepley if (!effectiveHeight) {sp[f] = cellsp[f];} 38954ee0cceSMatthew G. Knepley else {ierr = PetscDualSpaceGetHeightSubspace(cellsp[f], effectiveHeight, &sp[f]);CHKERRQ(ierr);} 39054ee0cceSMatthew G. Knepley } 39154ee0cceSMatthew G. Knepley ierr = PetscDualSpaceGetAllPointsUnion(Nf,sp,dim-effectiveHeight,funcs,&allPoints);CHKERRQ(ierr); 392c330f8ffSToby Isaac ierr = PetscQuadratureGetData(allPoints,NULL,NULL,&numPoints,&points,NULL);CHKERRQ(ierr); 3930c898c18SMatthew G. Knepley ierr = PetscMalloc4(Nf, &basisTab, Nf, &basisDerTab, NfAux, &basisTabAux, NfAux, &basisDerTabAux);CHKERRQ(ierr); 3940c898c18SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 3950c898c18SMatthew G. Knepley if (!isFE[f]) continue; 3960c898c18SMatthew G. Knepley ierr = PetscDSGetDiscretization(prob, f, (PetscObject *) &fem);CHKERRQ(ierr); 39774fc349aSMatthew G. Knepley if (!effectiveHeight) {subfem = fem;} 39874fc349aSMatthew G. Knepley else {ierr = PetscFEGetHeightSubspace(fem, effectiveHeight, &subfem);CHKERRQ(ierr);} 39974fc349aSMatthew G. Knepley ierr = PetscFEGetTabulation(subfem, numPoints, points, &basisTab[f], &basisDerTab[f], NULL);CHKERRQ(ierr); 4000c898c18SMatthew G. Knepley } 4010c898c18SMatthew G. Knepley for (f = 0; f < NfAux; ++f) { 4020c898c18SMatthew G. Knepley ierr = PetscDSGetDiscretization(probAux, f, (PetscObject *) &fem);CHKERRQ(ierr); 40374fc349aSMatthew G. Knepley if (!effectiveHeight || auxBd) {subfem = fem;} 40474fc349aSMatthew G. Knepley else {ierr = PetscFEGetHeightSubspace(fem, effectiveHeight, &subfem);CHKERRQ(ierr);} 40574fc349aSMatthew G. Knepley ierr = PetscFEGetTabulation(subfem, numPoints, points, &basisTabAux[f], &basisDerTabAux[f], NULL);CHKERRQ(ierr); 4060c898c18SMatthew G. Knepley } 4070c898c18SMatthew G. Knepley } 40847923291SMatthew G. Knepley /* Note: We make no attempt to optimize for height. Higher height things just overwrite the lower height results. */ 4092af58022SMatthew G. Knepley for (h = minHeight; h <= maxHeight; h++) { 41088aca1feSMatthew G. Knepley PetscInt effectiveHeight = h - (auxBd ? 0 : minHeight); 4110de51b56SMatthew G. Knepley PetscDS probEff = prob; 4128c6c5593SMatthew G. Knepley PetscScalar *values; 413b7260050SToby Isaac PetscBool *fieldActive; 414b7260050SToby Isaac PetscInt maxDegree; 415*e5e52638SMatthew G. Knepley PetscInt pStart, pEnd, p, lStart, spDim, totDim, numValues; 416c330f8ffSToby Isaac IS heightIS; 4178c6c5593SMatthew G. Knepley 41847923291SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, h, &pStart, &pEnd);CHKERRQ(ierr); 419*e5e52638SMatthew G. Knepley ierr = DMGetFirstLabelEntry_Private(dm, label, numIds, ids, h, &lStart, NULL);CHKERRQ(ierr); 420c330f8ffSToby Isaac ierr = DMLabelGetStratumIS(depthLabel, depth - h, &heightIS);CHKERRQ(ierr); 4218c6c5593SMatthew G. Knepley if (!h) { 4228c6c5593SMatthew G. Knepley PetscInt cEndInterior; 4238c6c5593SMatthew G. Knepley 4248c6c5593SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cEndInterior, NULL, NULL, NULL);CHKERRQ(ierr); 4258c6c5593SMatthew G. Knepley pEnd = cEndInterior < 0 ? pEnd : cEndInterior; 4268c6c5593SMatthew G. Knepley } 427c330f8ffSToby Isaac if (pEnd <= pStart) { 428c330f8ffSToby Isaac ierr = ISDestroy(&heightIS);CHKERRQ(ierr); 429c330f8ffSToby Isaac continue; 430c330f8ffSToby Isaac } 43147923291SMatthew G. Knepley /* Compute totDim, the number of dofs in the closure of a point at this height */ 43247923291SMatthew G. Knepley totDim = 0; 43347923291SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 434bec1f4aaSMatthew G. Knepley if (!effectiveHeight) { 43547923291SMatthew G. Knepley sp[f] = cellsp[f]; 43647923291SMatthew G. Knepley } else { 437bec1f4aaSMatthew G. Knepley ierr = PetscDualSpaceGetHeightSubspace(cellsp[f], effectiveHeight, &sp[f]);CHKERRQ(ierr); 43847923291SMatthew G. Knepley if (!sp[f]) continue; 43947923291SMatthew G. Knepley } 44047923291SMatthew G. Knepley ierr = PetscDualSpaceGetDimension(sp[f], &spDim);CHKERRQ(ierr); 4419c3cf19fSMatthew G. Knepley totDim += spDim; 44247923291SMatthew G. Knepley } 443*e5e52638SMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, section, localX, lStart < 0 ? pStart : lStart, &numValues, NULL);CHKERRQ(ierr); 4448c6c5593SMatthew 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); 445c330f8ffSToby Isaac if (!totDim) { 446c330f8ffSToby Isaac ierr = ISDestroy(&heightIS);CHKERRQ(ierr); 447c330f8ffSToby Isaac continue; 448c330f8ffSToby Isaac } 449c9731667SStefano Zampini if (effectiveHeight) {ierr = PetscDSGetHeightSubspace(prob, effectiveHeight, &probEff);CHKERRQ(ierr);} 45047923291SMatthew G. Knepley /* Loop over points at this height */ 45169291d52SBarry Smith ierr = DMGetWorkArray(dm, numValues, MPIU_SCALAR, &values);CHKERRQ(ierr); 45269291d52SBarry Smith ierr = DMGetWorkArray(dm, Nf, MPI_INT, &fieldActive);CHKERRQ(ierr); 4538c6c5593SMatthew G. Knepley for (f = 0; f < Nf; ++f) fieldActive[f] = (funcs[f] && sp[f]) ? PETSC_TRUE : PETSC_FALSE; 4548c6c5593SMatthew G. Knepley if (label) { 4558c6c5593SMatthew G. Knepley PetscInt i; 45647923291SMatthew G. Knepley 45747923291SMatthew G. Knepley for (i = 0; i < numIds; ++i) { 458c330f8ffSToby Isaac IS pointIS, isectIS; 45947923291SMatthew G. Knepley const PetscInt *points; 4608c6c5593SMatthew G. Knepley PetscInt n; 461c330f8ffSToby Isaac PetscFEGeom *fegeom = NULL, *chunkgeom = NULL; 462c330f8ffSToby Isaac PetscQuadrature quad = NULL; 46347923291SMatthew G. Knepley 46447923291SMatthew G. Knepley ierr = DMLabelGetStratumIS(label, ids[i], &pointIS);CHKERRQ(ierr); 46547923291SMatthew G. Knepley if (!pointIS) continue; /* No points with that id on this process */ 466c330f8ffSToby Isaac ierr = ISIntersect(pointIS,heightIS,&isectIS);CHKERRQ(ierr); 467c330f8ffSToby Isaac ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 468c330f8ffSToby Isaac if (!isectIS) continue; 469c330f8ffSToby Isaac ierr = ISGetLocalSize(isectIS, &n);CHKERRQ(ierr); 470c330f8ffSToby Isaac ierr = ISGetIndices(isectIS, &points);CHKERRQ(ierr); 471b7260050SToby Isaac ierr = DMFieldGetDegree(coordField,isectIS,NULL,&maxDegree);CHKERRQ(ierr); 472b7260050SToby Isaac if (maxDegree <= 1) { 473c330f8ffSToby Isaac ierr = DMFieldCreateDefaultQuadrature(coordField,isectIS,&quad);CHKERRQ(ierr); 474c330f8ffSToby Isaac } 475c330f8ffSToby Isaac if (!quad) { 476c330f8ffSToby Isaac if (!h && allPoints) { 477c330f8ffSToby Isaac quad = allPoints; 478c330f8ffSToby Isaac allPoints = NULL; 479c330f8ffSToby Isaac } else { 480c330f8ffSToby Isaac ierr = PetscDualSpaceGetAllPointsUnion(Nf,sp,dim-h,funcs,&quad);CHKERRQ(ierr); 481c330f8ffSToby Isaac } 482c330f8ffSToby Isaac } 483c330f8ffSToby Isaac ierr = DMFieldCreateFEGeom(coordField,isectIS,quad,PETSC_FALSE,&fegeom);CHKERRQ(ierr); 48447923291SMatthew G. Knepley for (p = 0; p < n; ++p) { 48547923291SMatthew G. Knepley const PetscInt point = points[p]; 48647923291SMatthew G. Knepley 487b420b6ccSMatthew G. Knepley ierr = PetscMemzero(values, numValues * sizeof(PetscScalar));CHKERRQ(ierr); 488c330f8ffSToby Isaac ierr = PetscFEGeomGetChunk(fegeom,p,p+1,&chunkgeom);CHKERRQ(ierr); 489c330f8ffSToby Isaac ierr = DMProjectPoint_Private(dm, probEff, chunkgeom, dmAux, probAux, effectiveHeight, time, localU, localA, hasFE, hasFV, isFE, sp, point, Ncc, comps, basisTab, basisDerTab, basisTabAux, basisDerTabAux, type, funcs, ctxs, fieldActive, values); 49047923291SMatthew G. Knepley if (ierr) { 49147923291SMatthew G. Knepley PetscErrorCode ierr2; 49269291d52SBarry Smith ierr2 = DMRestoreWorkArray(dm, numValues, MPIU_SCALAR, &values);CHKERRQ(ierr2); 49369291d52SBarry Smith ierr2 = DMRestoreWorkArray(dm, Nf, MPI_INT, &fieldActive);CHKERRQ(ierr2); 49447923291SMatthew G. Knepley CHKERRQ(ierr); 49547923291SMatthew G. Knepley } 496ba322698SMatthew G. Knepley ierr = DMPlexVecSetFieldClosure_Internal(dm, section, localX, fieldActive, point, Ncc, comps, values, mode);CHKERRQ(ierr); 49747923291SMatthew G. Knepley } 498c330f8ffSToby Isaac ierr = PetscFEGeomRestoreChunk(fegeom,p,p+1,&chunkgeom);CHKERRQ(ierr); 499c330f8ffSToby Isaac ierr = PetscFEGeomDestroy(&fegeom);CHKERRQ(ierr); 500c330f8ffSToby Isaac ierr = PetscQuadratureDestroy(&quad);CHKERRQ(ierr); 501c330f8ffSToby Isaac ierr = ISRestoreIndices(isectIS, &points);CHKERRQ(ierr); 502c330f8ffSToby Isaac ierr = ISDestroy(&isectIS);CHKERRQ(ierr); 50347923291SMatthew G. Knepley } 5048c6c5593SMatthew G. Knepley } else { 505c330f8ffSToby Isaac PetscFEGeom *fegeom = NULL, *chunkgeom = NULL; 506c330f8ffSToby Isaac PetscQuadrature quad = NULL; 507c330f8ffSToby Isaac IS pointIS; 508c330f8ffSToby Isaac 509c330f8ffSToby Isaac ierr = ISCreateStride(PETSC_COMM_SELF,pEnd-pStart,pStart,1,&pointIS);CHKERRQ(ierr); 510b7260050SToby Isaac ierr = DMFieldGetDegree(coordField,pointIS,NULL,&maxDegree);CHKERRQ(ierr); 511b7260050SToby Isaac if (maxDegree <= 1) { 512c330f8ffSToby Isaac ierr = DMFieldCreateDefaultQuadrature(coordField,pointIS,&quad);CHKERRQ(ierr); 513c330f8ffSToby Isaac } 514c330f8ffSToby Isaac if (!quad) { 515c330f8ffSToby Isaac if (!h && allPoints) { 516c330f8ffSToby Isaac quad = allPoints; 517c330f8ffSToby Isaac allPoints = NULL; 518c330f8ffSToby Isaac } else { 519c330f8ffSToby Isaac ierr = PetscDualSpaceGetAllPointsUnion(Nf,sp,dim-h,funcs,&quad);CHKERRQ(ierr); 520c330f8ffSToby Isaac } 521c330f8ffSToby Isaac } 522c330f8ffSToby Isaac ierr = DMFieldCreateFEGeom(coordField,pointIS,quad,PETSC_FALSE,&fegeom);CHKERRQ(ierr); 5238c6c5593SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 524b420b6ccSMatthew G. Knepley ierr = PetscMemzero(values, numValues * sizeof(PetscScalar));CHKERRQ(ierr); 525c330f8ffSToby Isaac ierr = PetscFEGeomGetChunk(fegeom,p-pStart,p-pStart+1,&chunkgeom);CHKERRQ(ierr); 526c330f8ffSToby Isaac ierr = DMProjectPoint_Private(dm, probEff, chunkgeom, dmAux, probAux, effectiveHeight, time, localU, localA, hasFE, hasFV, isFE, sp, p, Ncc, comps, basisTab, basisDerTab, basisTabAux, basisDerTabAux, type, funcs, ctxs, fieldActive, values); 5278c6c5593SMatthew G. Knepley if (ierr) { 5288c6c5593SMatthew G. Knepley PetscErrorCode ierr2; 52969291d52SBarry Smith ierr2 = DMRestoreWorkArray(dm, numValues, MPIU_SCALAR, &values);CHKERRQ(ierr2); 53069291d52SBarry Smith ierr2 = DMRestoreWorkArray(dm, Nf, MPI_INT, &fieldActive);CHKERRQ(ierr2); 5318c6c5593SMatthew G. Knepley CHKERRQ(ierr); 5328c6c5593SMatthew G. Knepley } 533ba322698SMatthew G. Knepley ierr = DMPlexVecSetFieldClosure_Internal(dm, section, localX, fieldActive, p, Ncc, comps, values, mode);CHKERRQ(ierr); 5348c6c5593SMatthew G. Knepley } 535c330f8ffSToby Isaac ierr = PetscFEGeomRestoreChunk(fegeom,p-pStart,pStart-p+1,&chunkgeom);CHKERRQ(ierr); 536c330f8ffSToby Isaac ierr = PetscFEGeomDestroy(&fegeom);CHKERRQ(ierr); 537c330f8ffSToby Isaac ierr = PetscQuadratureDestroy(&quad);CHKERRQ(ierr); 538c330f8ffSToby Isaac ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 5398c6c5593SMatthew G. Knepley } 540c330f8ffSToby Isaac ierr = ISDestroy(&heightIS);CHKERRQ(ierr); 54169291d52SBarry Smith ierr = DMRestoreWorkArray(dm, numValues, MPIU_SCALAR, &values);CHKERRQ(ierr); 54269291d52SBarry Smith ierr = DMRestoreWorkArray(dm, Nf, MPI_INT, &fieldActive);CHKERRQ(ierr); 54347923291SMatthew G. Knepley } 5448c6c5593SMatthew G. Knepley /* Cleanup */ 5450c898c18SMatthew G. Knepley if (type == DM_BC_ESSENTIAL_FIELD || type == DM_BC_NATURAL_FIELD) { 54674fc349aSMatthew G. Knepley PetscInt effectiveHeight = auxBd ? minHeight : 0; 54774fc349aSMatthew G. Knepley PetscFE fem, subfem; 5480c898c18SMatthew G. Knepley 5490c898c18SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5500c898c18SMatthew G. Knepley if (!isFE[f]) continue; 5510c898c18SMatthew G. Knepley ierr = PetscDSGetDiscretization(prob, f, (PetscObject *) &fem);CHKERRQ(ierr); 55274fc349aSMatthew G. Knepley if (!effectiveHeight) {subfem = fem;} 55374fc349aSMatthew G. Knepley else {ierr = PetscFEGetHeightSubspace(fem, effectiveHeight, &subfem);CHKERRQ(ierr);} 55474fc349aSMatthew G. Knepley ierr = PetscFERestoreTabulation(subfem, 0, NULL, &basisTab[f], &basisDerTab[f], NULL);CHKERRQ(ierr); 5550c898c18SMatthew G. Knepley } 5560c898c18SMatthew G. Knepley for (f = 0; f < NfAux; ++f) { 5570c898c18SMatthew G. Knepley ierr = PetscDSGetDiscretization(probAux, f, (PetscObject *) &fem);CHKERRQ(ierr); 55874fc349aSMatthew G. Knepley if (!effectiveHeight || auxBd) {subfem = fem;} 55974fc349aSMatthew G. Knepley else {ierr = PetscFEGetHeightSubspace(fem, effectiveHeight, &subfem);CHKERRQ(ierr);} 56074fc349aSMatthew G. Knepley ierr = PetscFERestoreTabulation(subfem, 0, NULL, &basisTabAux[f], &basisDerTabAux[f], NULL);CHKERRQ(ierr); 5610c898c18SMatthew G. Knepley } 5620c898c18SMatthew G. Knepley ierr = PetscFree4(basisTab, basisDerTab, basisTabAux, basisDerTabAux);CHKERRQ(ierr); 5630c898c18SMatthew G. Knepley } 564c330f8ffSToby Isaac ierr = PetscQuadratureDestroy(&allPoints);CHKERRQ(ierr); 565496733e2SMatthew G. Knepley ierr = PetscFree2(isFE, sp);CHKERRQ(ierr); 5668c6c5593SMatthew G. Knepley if (maxHeight > 0) {ierr = PetscFree(cellsp);CHKERRQ(ierr);} 5678c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 56847923291SMatthew G. Knepley } 5698c6c5593SMatthew G. Knepley 5708c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFunctionLocal_Plex(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX) 5718c6c5593SMatthew G. Knepley { 5728c6c5593SMatthew G. Knepley PetscErrorCode ierr; 5738c6c5593SMatthew G. Knepley 5748c6c5593SMatthew G. Knepley PetscFunctionBegin; 5751c531cf8SMatthew 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); 5768c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 5778c6c5593SMatthew G. Knepley } 5788c6c5593SMatthew G. Knepley 5791c531cf8SMatthew 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) 5808c6c5593SMatthew G. Knepley { 5818c6c5593SMatthew G. Knepley PetscErrorCode ierr; 5828c6c5593SMatthew G. Knepley 5838c6c5593SMatthew G. Knepley PetscFunctionBegin; 5841c531cf8SMatthew 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); 58547923291SMatthew G. Knepley PetscFunctionReturn(0); 58647923291SMatthew G. Knepley } 58747923291SMatthew G. Knepley 5888c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFieldLocal_Plex(DM dm, PetscReal time, Vec localU, 58947923291SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 59047923291SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 59147923291SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 592191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 59347923291SMatthew G. Knepley InsertMode mode, Vec localX) 59447923291SMatthew G. Knepley { 59547923291SMatthew G. Knepley PetscErrorCode ierr; 59647923291SMatthew G. Knepley 59747923291SMatthew G. Knepley PetscFunctionBegin; 5981c531cf8SMatthew 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); 5998c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 60047923291SMatthew G. Knepley } 60147923291SMatthew G. Knepley 6021c531cf8SMatthew G. Knepley PetscErrorCode DMProjectFieldLabelLocal_Plex(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Ncc, const PetscInt comps[], Vec localU, 6038c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 6048c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 6058c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 606191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 6078c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 6088c6c5593SMatthew G. Knepley { 6098c6c5593SMatthew G. Knepley PetscErrorCode ierr; 61047923291SMatthew G. Knepley 6118c6c5593SMatthew G. Knepley PetscFunctionBegin; 6121c531cf8SMatthew 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); 61347923291SMatthew G. Knepley PetscFunctionReturn(0); 61447923291SMatthew G. Knepley } 615