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 51b32699bSMatthew G. Knepley /*@ 61b32699bSMatthew G. Knepley DMPlexGetActivePoint - Get the point on which projection is currently working 71b32699bSMatthew G. Knepley 81b32699bSMatthew G. Knepley Not collective 91b32699bSMatthew G. Knepley 104165533cSJose E. Roman Input Parameter: 111b32699bSMatthew G. Knepley . dm - the DM 121b32699bSMatthew G. Knepley 134165533cSJose E. Roman Output Parameter: 141b32699bSMatthew G. Knepley . point - The mesh point involved in the current projection 151b32699bSMatthew G. Knepley 161b32699bSMatthew G. Knepley Level: developer 171b32699bSMatthew G. Knepley 181b32699bSMatthew G. Knepley .seealso: DMPlexSetActivePoint() 191b32699bSMatthew G. Knepley @*/ 20bdb10af2SPierre Jolivet PetscErrorCode DMPlexGetActivePoint(DM dm, PetscInt *point) 21bdb10af2SPierre Jolivet { 221b32699bSMatthew G. Knepley PetscFunctionBeginHot; 231b32699bSMatthew G. Knepley *point = ((DM_Plex *) dm->data)->activePoint; 241b32699bSMatthew G. Knepley PetscFunctionReturn(0); 251b32699bSMatthew G. Knepley } 261b32699bSMatthew G. Knepley 271b32699bSMatthew G. Knepley /*@ 281b32699bSMatthew G. Knepley DMPlexSetActivePoint - Set the point on which projection is currently working 291b32699bSMatthew G. Knepley 301b32699bSMatthew G. Knepley Not collective 311b32699bSMatthew G. Knepley 324165533cSJose E. Roman Input Parameters: 331b32699bSMatthew G. Knepley + dm - the DM 341b32699bSMatthew G. Knepley - point - The mesh point involved in the current projection 351b32699bSMatthew G. Knepley 361b32699bSMatthew G. Knepley Level: developer 371b32699bSMatthew G. Knepley 381b32699bSMatthew G. Knepley .seealso: DMPlexGetActivePoint() 391b32699bSMatthew G. Knepley @*/ 40bdb10af2SPierre Jolivet PetscErrorCode DMPlexSetActivePoint(DM dm, PetscInt point) 41bdb10af2SPierre Jolivet { 421b32699bSMatthew G. Knepley PetscFunctionBeginHot; 431b32699bSMatthew G. Knepley ((DM_Plex *) dm->data)->activePoint = point; 441b32699bSMatthew G. Knepley PetscFunctionReturn(0); 451b32699bSMatthew G. Knepley } 461b32699bSMatthew G. Knepley 47a6e0b375SMatthew G. Knepley /* 48a6e0b375SMatthew G. Knepley DMProjectPoint_Func_Private - Interpolate the given function in the output basis on the given point 49a6e0b375SMatthew G. Knepley 50a6e0b375SMatthew G. Knepley Input Parameters: 51a6e0b375SMatthew G. Knepley + dm - The output DM 52a6e0b375SMatthew G. Knepley . ds - The output DS 53a6e0b375SMatthew G. Knepley . dmIn - The input DM 54a6e0b375SMatthew G. Knepley . dsIn - The input DS 55a6e0b375SMatthew G. Knepley . time - The time for this evaluation 56a6e0b375SMatthew G. Knepley . fegeom - The FE geometry for this point 57a6e0b375SMatthew G. Knepley . fvgeom - The FV geometry for this point 58a6e0b375SMatthew G. Knepley . isFE - Flag indicating whether each output field has an FE discretization 59a6e0b375SMatthew G. Knepley . sp - The output PetscDualSpace for each field 60a6e0b375SMatthew G. Knepley . funcs - The evaluation function for each field 61a6e0b375SMatthew G. Knepley - ctxs - The user context for each field 62a6e0b375SMatthew G. Knepley 63a6e0b375SMatthew G. Knepley Output Parameter: 64a6e0b375SMatthew G. Knepley . values - The value for each dual basis vector in the output dual space 65a6e0b375SMatthew G. Knepley 66a6e0b375SMatthew G. Knepley Level: developer 67a6e0b375SMatthew G. Knepley 68a6e0b375SMatthew G. Knepley .seealso: DMProjectPoint_Field_Private() 69a6e0b375SMatthew G. Knepley */ 70a6e0b375SMatthew 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[], 718c6c5593SMatthew G. Knepley PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, 728c6c5593SMatthew G. Knepley PetscScalar values[]) 7347923291SMatthew G. Knepley { 74a6e0b375SMatthew G. Knepley PetscInt coordDim, Nf, *Nc, f, spDim, d, v, tp; 755fedec97SMatthew G. Knepley PetscBool isAffine, isCohesive, transform; 768c6c5593SMatthew G. Knepley 778c6c5593SMatthew G. Knepley PetscFunctionBeginHot; 78*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetCoordinateDim(dmIn, &coordDim)); 79*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMHasBasisTransform(dmIn, &transform)); 80*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(ds, &Nf)); 81*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponents(ds, &Nc)); 82*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSIsCohesive(ds, &isCohesive)); 838c6c5593SMatthew G. Knepley /* Get values for closure */ 84c330f8ffSToby Isaac isAffine = fegeom->isAffine; 85c330f8ffSToby Isaac for (f = 0, v = 0, tp = 0; f < Nf; ++f) { 868c6c5593SMatthew G. Knepley void * const ctx = ctxs ? ctxs[f] : NULL; 875fedec97SMatthew G. Knepley PetscBool cohesive; 888c6c5593SMatthew G. Knepley 898c6c5593SMatthew G. Knepley if (!sp[f]) continue; 90*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetCohesive(ds, f, &cohesive)); 91*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDimension(sp[f], &spDim)); 928c6c5593SMatthew G. Knepley if (funcs[f]) { 93c330f8ffSToby Isaac if (isFE[f]) { 94c330f8ffSToby Isaac PetscQuadrature allPoints; 95c330f8ffSToby Isaac PetscInt q, dim, numPoints; 96c330f8ffSToby Isaac const PetscReal *points; 97c330f8ffSToby Isaac PetscScalar *pointEval; 98c330f8ffSToby Isaac PetscReal *x; 99ca3d3a14SMatthew G. Knepley DM rdm; 100c330f8ffSToby Isaac 101*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDM(sp[f],&rdm)); 102*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetAllData(sp[f], &allPoints, NULL)); 103*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetData(allPoints,&dim,NULL,&numPoints,&points,NULL)); 104*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetWorkArray(rdm,numPoints*Nc[f],MPIU_SCALAR,&pointEval)); 105*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetWorkArray(rdm,coordDim,MPIU_REAL,&x)); 106c330f8ffSToby Isaac for (q = 0; q < numPoints; q++, tp++) { 107c330f8ffSToby Isaac const PetscReal *v0; 108c330f8ffSToby Isaac 109c330f8ffSToby Isaac if (isAffine) { 110665f567fSMatthew G. Knepley const PetscReal *refpoint = &points[q*dim]; 111665f567fSMatthew G. Knepley PetscReal injpoint[3] = {0., 0., 0.}; 112665f567fSMatthew G. Knepley 113665f567fSMatthew G. Knepley if (dim != fegeom->dim) { 1145fedec97SMatthew G. Knepley if (isCohesive) { 115665f567fSMatthew G. Knepley /* We just need to inject into the higher dimensional space assuming the last dimension is collapsed */ 116665f567fSMatthew G. Knepley for (d = 0; d < dim; ++d) injpoint[d] = refpoint[d]; 117665f567fSMatthew G. Knepley refpoint = injpoint; 11898921bdaSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Reference spatial dimension %D != %D dual basis spatial dimension", fegeom->dim, dim); 119665f567fSMatthew G. Knepley } 120665f567fSMatthew G. Knepley CoordinatesRefToReal(coordDim, fegeom->dim, fegeom->xi, fegeom->v, fegeom->J, refpoint, x); 121c330f8ffSToby Isaac v0 = x; 1228c6c5593SMatthew G. Knepley } else { 123c330f8ffSToby Isaac v0 = &fegeom->v[tp*coordDim]; 1248c6c5593SMatthew G. Knepley } 125*5f80ce2aSJacob Faibussowitsch if (transform) {CHKERRQ(DMPlexBasisTransformApplyReal_Internal(dmIn, v0, PETSC_TRUE, coordDim, v0, x, dm->transformCtx)); v0 = x;} 126*5f80ce2aSJacob Faibussowitsch CHKERRQ((*funcs[f])(coordDim, time, v0, Nc[f], &pointEval[Nc[f]*q], ctx)); 127c330f8ffSToby Isaac } 1284bee2e38SMatthew G. Knepley /* Transform point evaluations pointEval[q,c] */ 129*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpacePullback(sp[f], fegeom, numPoints, Nc[f], pointEval)); 130*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceApplyAll(sp[f], pointEval, &values[v])); 131*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreWorkArray(rdm,coordDim,MPIU_REAL,&x)); 132*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreWorkArray(rdm,numPoints*Nc[f],MPIU_SCALAR,&pointEval)); 133c330f8ffSToby Isaac v += spDim; 1345fedec97SMatthew G. Knepley if (isCohesive && !cohesive) { 13527f02ce8SMatthew G. Knepley for (d = 0; d < spDim; d++, v++) values[v] = values[v - spDim]; 13627f02ce8SMatthew G. Knepley } 137c330f8ffSToby Isaac } else { 138c330f8ffSToby Isaac for (d = 0; d < spDim; ++d, ++v) { 139*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceApplyFVM(sp[f], d, time, fvgeom, Nc[f], funcs[f], ctx, &values[v])); 140c330f8ffSToby Isaac } 141c330f8ffSToby Isaac } 142c330f8ffSToby Isaac } else { 14327f02ce8SMatthew G. Knepley for (d = 0; d < spDim; d++, v++) values[v] = 0.; 1445fedec97SMatthew G. Knepley if (isCohesive && !cohesive) { 14527f02ce8SMatthew G. Knepley for (d = 0; d < spDim; d++, v++) values[v] = 0.; 14627f02ce8SMatthew G. Knepley } 1478c6c5593SMatthew G. Knepley } 1489c3cf19fSMatthew G. Knepley } 1498c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 1508c6c5593SMatthew G. Knepley } 1518c6c5593SMatthew G. Knepley 152a6e0b375SMatthew G. Knepley /* 153a6e0b375SMatthew G. Knepley DMProjectPoint_Field_Private - Interpolate a function of the given field, in the input basis, using the output basis on the given point 154a6e0b375SMatthew G. Knepley 155a6e0b375SMatthew G. Knepley Input Parameters: 156a6e0b375SMatthew G. Knepley + dm - The output DM 157a6e0b375SMatthew G. Knepley . ds - The output DS 158a6e0b375SMatthew G. Knepley . dmIn - The input DM 159a6e0b375SMatthew G. Knepley . dsIn - The input DS 160a6e0b375SMatthew G. Knepley . dmAux - The auxiliary DM, which is always for the input space 161a6e0b375SMatthew G. Knepley . dsAux - The auxiliary DS, which is always for the input space 162a6e0b375SMatthew G. Knepley . time - The time for this evaluation 163a6e0b375SMatthew G. Knepley . localU - The local solution 164a6e0b375SMatthew G. Knepley . localA - The local auziliary fields 165a6e0b375SMatthew G. Knepley . cgeom - The FE geometry for this point 166a6e0b375SMatthew G. Knepley . sp - The output PetscDualSpace for each field 167a6e0b375SMatthew G. Knepley . p - The point in the output DM 168a5b23f4aSJose E. Roman . T - Input basis and derivatives for each field tabulated on the quadrature points 169ef0bb6c7SMatthew G. Knepley . TAux - Auxiliary basis and derivatives for each aux field tabulated on the quadrature points 170a6e0b375SMatthew G. Knepley . funcs - The evaluation function for each field 171a6e0b375SMatthew G. Knepley - ctxs - The user context for each field 172a6e0b375SMatthew G. Knepley 173a6e0b375SMatthew G. Knepley Output Parameter: 174a6e0b375SMatthew G. Knepley . values - The value for each dual basis vector in the output dual space 175a6e0b375SMatthew G. Knepley 176a6e0b375SMatthew G. Knepley Note: Not supported for FV 177a6e0b375SMatthew G. Knepley 178a6e0b375SMatthew G. Knepley Level: developer 179a6e0b375SMatthew G. Knepley 180a6e0b375SMatthew G. Knepley .seealso: DMProjectPoint_Field_Private() 181a6e0b375SMatthew G. Knepley */ 182a6e0b375SMatthew 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, 183ef0bb6c7SMatthew G. Knepley PetscTabulation *T, PetscTabulation *TAux, 1848c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 1858c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 1868c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 187191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void **ctxs, 1888c6c5593SMatthew G. Knepley PetscScalar values[]) 1898c6c5593SMatthew G. Knepley { 1908c6c5593SMatthew G. Knepley PetscSection section, sectionAux = NULL; 1914bee2e38SMatthew G. Knepley PetscScalar *u, *u_t = NULL, *u_x, *a = NULL, *a_t = NULL, *a_x = NULL, *bc; 1928c6c5593SMatthew G. Knepley PetscScalar *coefficients = NULL, *coefficientsAux = NULL; 1938c6c5593SMatthew G. Knepley PetscScalar *coefficients_t = NULL, *coefficientsAux_t = NULL; 194191494d9SMatthew G. Knepley const PetscScalar *constants; 1958c6c5593SMatthew G. Knepley PetscReal *x; 196ef0bb6c7SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL, *Nc; 1974bee2e38SMatthew G. Knepley PetscFEGeom fegeom; 1984bee2e38SMatthew G. Knepley const PetscInt dE = cgeom->dimEmbed; 199ef0bb6c7SMatthew G. Knepley PetscInt numConstants, Nf, NfIn, NfAux = 0, f, spDim, d, v, inp, tp = 0; 2005fedec97SMatthew G. Knepley PetscBool isAffine, isCohesive, transform; 2018c6c5593SMatthew G. Knepley 2028c6c5593SMatthew G. Knepley PetscFunctionBeginHot; 203*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(ds, &Nf)); 204*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponents(ds, &Nc)); 205*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSIsCohesive(ds, &isCohesive)); 206*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(dsIn, &NfIn)); 207*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentOffsets(dsIn, &uOff)); 208*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentDerivativeOffsets(dsIn, &uOff_x)); 209*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetEvaluationArrays(dsIn, &u, &bc /*&u_t*/, &u_x)); 210*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetWorkspace(dsIn, &x, NULL, NULL, NULL, NULL)); 211*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetConstants(dsIn, &numConstants, &constants)); 212*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMHasBasisTransform(dmIn, &transform)); 213*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetLocalSection(dmIn, §ion)); 214*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetEnclosurePoint(dmIn, dm, encIn, p, &inp)); 215*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexVecGetClosure(dmIn, section, localU, inp, NULL, &coefficients)); 2168c6c5593SMatthew G. Knepley if (dmAux) { 21744171101SMatthew G. Knepley PetscInt subp; 2181ba34526SMatthew G. Knepley 219*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetEnclosurePoint(dmAux, dm, encAux, p, &subp)); 220*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(dsAux, &NfAux)); 221*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetLocalSection(dmAux, §ionAux)); 222*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentOffsets(dsAux, &aOff)); 223*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x)); 224*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetEvaluationArrays(dsAux, &a, NULL /*&a_t*/, &a_x)); 225*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexVecGetClosure(dmAux, sectionAux, localA, subp, NULL, &coefficientsAux)); 2268c6c5593SMatthew G. Knepley } 2278c6c5593SMatthew G. Knepley /* Get values for closure */ 2284bee2e38SMatthew G. Knepley isAffine = cgeom->isAffine; 22927f02ce8SMatthew G. Knepley fegeom.dim = cgeom->dim; 23027f02ce8SMatthew G. Knepley fegeom.dimEmbed = cgeom->dimEmbed; 2314bee2e38SMatthew G. Knepley if (isAffine) { 2324bee2e38SMatthew G. Knepley fegeom.v = x; 2334bee2e38SMatthew G. Knepley fegeom.xi = cgeom->xi; 2344bee2e38SMatthew G. Knepley fegeom.J = cgeom->J; 2354bee2e38SMatthew G. Knepley fegeom.invJ = cgeom->invJ; 2364bee2e38SMatthew G. Knepley fegeom.detJ = cgeom->detJ; 2374bee2e38SMatthew G. Knepley } 2388c6c5593SMatthew G. Knepley for (f = 0, v = 0; f < Nf; ++f) { 239c330f8ffSToby Isaac PetscQuadrature allPoints; 240c330f8ffSToby Isaac PetscInt q, dim, numPoints; 241c330f8ffSToby Isaac const PetscReal *points; 242c330f8ffSToby Isaac PetscScalar *pointEval; 2435fedec97SMatthew G. Knepley PetscBool cohesive; 244c330f8ffSToby Isaac DM dm; 245c330f8ffSToby Isaac 2468c6c5593SMatthew G. Knepley if (!sp[f]) continue; 247*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetCohesive(ds, f, &cohesive)); 248*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDimension(sp[f], &spDim)); 249c330f8ffSToby Isaac if (!funcs[f]) { 250be1504a2SMatthew G. Knepley for (d = 0; d < spDim; d++, v++) values[v] = 0.; 2515fedec97SMatthew G. Knepley if (isCohesive && !cohesive) { 25227f02ce8SMatthew G. Knepley for (d = 0; d < spDim; d++, v++) values[v] = 0.; 25327f02ce8SMatthew G. Knepley } 254c330f8ffSToby Isaac continue; 255c330f8ffSToby Isaac } 256*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDM(sp[f],&dm)); 257*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetAllData(sp[f], &allPoints, NULL)); 258*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetData(allPoints,&dim,NULL,&numPoints,&points,NULL)); 259*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetWorkArray(dm,numPoints*Nc[f],MPIU_SCALAR,&pointEval)); 2600c898c18SMatthew G. Knepley for (q = 0; q < numPoints; ++q, ++tp) { 261c330f8ffSToby Isaac if (isAffine) { 262ef0bb6c7SMatthew G. Knepley CoordinatesRefToReal(dE, cgeom->dim, fegeom.xi, cgeom->v, fegeom.J, &points[q*dim], x); 2631c531cf8SMatthew G. Knepley } else { 2644bee2e38SMatthew G. Knepley fegeom.v = &cgeom->v[tp*dE]; 2654bee2e38SMatthew G. Knepley fegeom.J = &cgeom->J[tp*dE*dE]; 2664bee2e38SMatthew G. Knepley fegeom.invJ = &cgeom->invJ[tp*dE*dE]; 2674bee2e38SMatthew G. Knepley fegeom.detJ = &cgeom->detJ[tp]; 2688c6c5593SMatthew G. Knepley } 269*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEEvaluateFieldJets_Internal(dsIn, NfIn, 0, tp, T, &fegeom, coefficients, coefficients_t, u, u_x, u_t)); 270*5f80ce2aSJacob Faibussowitsch if (dsAux) CHKERRQ(PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, 0, tp, TAux, &fegeom, coefficientsAux, coefficientsAux_t, a, a_x, a_t)); 271*5f80ce2aSJacob Faibussowitsch if (transform) CHKERRQ(DMPlexBasisTransformApplyReal_Internal(dmIn, fegeom.v, PETSC_TRUE, dE, fegeom.v, fegeom.v, dm->transformCtx)); 272a6e0b375SMatthew 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]); 2731c531cf8SMatthew G. Knepley } 274*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceApplyAll(sp[f], pointEval, &values[v])); 275*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreWorkArray(dm,numPoints*Nc[f],MPIU_SCALAR,&pointEval)); 276c330f8ffSToby Isaac v += spDim; 27727f02ce8SMatthew G. Knepley /* TODO: For now, set both sides equal, but this should use info from other support cell */ 2785fedec97SMatthew G. Knepley if (isCohesive && !cohesive) { 27927f02ce8SMatthew G. Knepley for (d = 0; d < spDim; d++, v++) values[v] = values[v - spDim]; 28027f02ce8SMatthew G. Knepley } 2818c6c5593SMatthew G. Knepley } 282*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexVecRestoreClosure(dmIn, section, localU, inp, NULL, &coefficients)); 283*5f80ce2aSJacob Faibussowitsch if (dmAux) CHKERRQ(DMPlexVecRestoreClosure(dmAux, sectionAux, localA, p, NULL, &coefficientsAux)); 2848c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 2858c6c5593SMatthew G. Knepley } 2868c6c5593SMatthew G. Knepley 287a6e0b375SMatthew 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, 288ef0bb6c7SMatthew G. Knepley PetscTabulation *T, PetscTabulation *TAux, 289b18799e0SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 290b18799e0SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 291b18799e0SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 292b18799e0SMatthew G. Knepley PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void **ctxs, 293b18799e0SMatthew G. Knepley PetscScalar values[]) 294b18799e0SMatthew G. Knepley { 295b18799e0SMatthew G. Knepley PetscSection section, sectionAux = NULL; 2964bee2e38SMatthew G. Knepley PetscScalar *u, *u_t = NULL, *u_x, *a = NULL, *a_t = NULL, *a_x = NULL, *bc; 297b18799e0SMatthew G. Knepley PetscScalar *coefficients = NULL, *coefficientsAux = NULL; 298b18799e0SMatthew G. Knepley PetscScalar *coefficients_t = NULL, *coefficientsAux_t = NULL; 299b18799e0SMatthew G. Knepley const PetscScalar *constants; 300b18799e0SMatthew G. Knepley PetscReal *x; 301ef0bb6c7SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL, *Nc; 3029f209ee4SMatthew G. Knepley PetscFEGeom fegeom, cgeom; 3034bee2e38SMatthew G. Knepley const PetscInt dE = fgeom->dimEmbed; 304ef0bb6c7SMatthew G. Knepley PetscInt numConstants, Nf, NfAux = 0, f, spDim, d, v, tp = 0; 305b18799e0SMatthew G. Knepley PetscBool isAffine; 306b18799e0SMatthew G. Knepley 307b18799e0SMatthew G. Knepley PetscFunctionBeginHot; 3082c71b3e2SJacob Faibussowitsch PetscCheckFalse(dm != dmIn,PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Not yet upgraded to use different input DM"); 309*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(ds, &Nf)); 310*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponents(ds, &Nc)); 311*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentOffsets(ds, &uOff)); 312*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentDerivativeOffsets(ds, &uOff_x)); 313*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetEvaluationArrays(ds, &u, &bc /*&u_t*/, &u_x)); 314*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetWorkspace(ds, &x, NULL, NULL, NULL, NULL)); 315*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetConstants(ds, &numConstants, &constants)); 316*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetLocalSection(dm, §ion)); 317*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexVecGetClosure(dmIn, section, localU, p, NULL, &coefficients)); 318b18799e0SMatthew G. Knepley if (dmAux) { 319a6e0b375SMatthew G. Knepley PetscInt subp; 320b18799e0SMatthew G. Knepley 321*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetEnclosurePoint(dmAux, dm, encAux, p, &subp)); 322*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(dsAux, &NfAux)); 323*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetLocalSection(dmAux, §ionAux)); 324*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentOffsets(dsAux, &aOff)); 325*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x)); 326*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetEvaluationArrays(dsAux, &a, NULL /*&a_t*/, &a_x)); 327*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexVecGetClosure(dmAux, sectionAux, localA, subp, NULL, &coefficientsAux)); 328b18799e0SMatthew G. Knepley } 329b18799e0SMatthew G. Knepley /* Get values for closure */ 3304bee2e38SMatthew G. Knepley isAffine = fgeom->isAffine; 331ea78f98cSLisandro Dalcin fegeom.n = NULL; 332ea78f98cSLisandro Dalcin fegeom.J = NULL; 333ea78f98cSLisandro Dalcin fegeom.v = NULL; 334ea78f98cSLisandro Dalcin fegeom.xi = NULL; 335a6e0b375SMatthew G. Knepley cgeom.dim = fgeom->dim; 336a6e0b375SMatthew G. Knepley cgeom.dimEmbed = fgeom->dimEmbed; 3374bee2e38SMatthew G. Knepley if (isAffine) { 3384bee2e38SMatthew G. Knepley fegeom.v = x; 3394bee2e38SMatthew G. Knepley fegeom.xi = fgeom->xi; 3404bee2e38SMatthew G. Knepley fegeom.J = fgeom->J; 3414bee2e38SMatthew G. Knepley fegeom.invJ = fgeom->invJ; 3424bee2e38SMatthew G. Knepley fegeom.detJ = fgeom->detJ; 3434bee2e38SMatthew G. Knepley fegeom.n = fgeom->n; 3449f209ee4SMatthew G. Knepley 3459f209ee4SMatthew G. Knepley cgeom.J = fgeom->suppJ[0]; 3469f209ee4SMatthew G. Knepley cgeom.invJ = fgeom->suppInvJ[0]; 3479f209ee4SMatthew G. Knepley cgeom.detJ = fgeom->suppDetJ[0]; 3484bee2e38SMatthew G. Knepley } 349b18799e0SMatthew G. Knepley for (f = 0, v = 0; f < Nf; ++f) { 350b18799e0SMatthew G. Knepley PetscQuadrature allPoints; 351b18799e0SMatthew G. Knepley PetscInt q, dim, numPoints; 352b18799e0SMatthew G. Knepley const PetscReal *points; 353b18799e0SMatthew G. Knepley PetscScalar *pointEval; 354b18799e0SMatthew G. Knepley DM dm; 355b18799e0SMatthew G. Knepley 356b18799e0SMatthew G. Knepley if (!sp[f]) continue; 357*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDimension(sp[f], &spDim)); 358b18799e0SMatthew G. Knepley if (!funcs[f]) { 359b18799e0SMatthew G. Knepley for (d = 0; d < spDim; d++, v++) values[v] = 0.; 360b18799e0SMatthew G. Knepley continue; 361b18799e0SMatthew G. Knepley } 362*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDM(sp[f],&dm)); 363*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetAllData(sp[f], &allPoints, NULL)); 364*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetData(allPoints,&dim,NULL,&numPoints,&points,NULL)); 365*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetWorkArray(dm,numPoints*Nc[f],MPIU_SCALAR,&pointEval)); 366b18799e0SMatthew G. Knepley for (q = 0; q < numPoints; ++q, ++tp) { 367b18799e0SMatthew G. Knepley if (isAffine) { 368ef0bb6c7SMatthew G. Knepley CoordinatesRefToReal(dE, fgeom->dim, fegeom.xi, fgeom->v, fegeom.J, &points[q*dim], x); 369b18799e0SMatthew G. Knepley } else { 3703fe841f2SMatthew G. Knepley fegeom.v = &fgeom->v[tp*dE]; 3719f209ee4SMatthew G. Knepley fegeom.J = &fgeom->J[tp*dE*dE]; 3729f209ee4SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[tp*dE*dE]; 3734bee2e38SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[tp]; 3744bee2e38SMatthew G. Knepley fegeom.n = &fgeom->n[tp*dE]; 3759f209ee4SMatthew G. Knepley 3769f209ee4SMatthew G. Knepley cgeom.J = &fgeom->suppJ[0][tp*dE*dE]; 3779f209ee4SMatthew G. Knepley cgeom.invJ = &fgeom->suppInvJ[0][tp*dE*dE]; 3789f209ee4SMatthew G. Knepley cgeom.detJ = &fgeom->suppDetJ[0][tp]; 379b18799e0SMatthew G. Knepley } 380a6e0b375SMatthew 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 */ 381*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEEvaluateFieldJets_Internal(ds, Nf, 0, tp, T, &cgeom, coefficients, coefficients_t, u, u_x, u_t)); 382*5f80ce2aSJacob Faibussowitsch if (dsAux) CHKERRQ(PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, 0, tp, TAux, &cgeom, coefficientsAux, coefficientsAux_t, a, a_x, a_t)); 3834bee2e38SMatthew 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]); 384b18799e0SMatthew G. Knepley } 385*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceApplyAll(sp[f], pointEval, &values[v])); 386*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreWorkArray(dm,numPoints*Nc[f],MPIU_SCALAR,&pointEval)); 387b18799e0SMatthew G. Knepley v += spDim; 388b18799e0SMatthew G. Knepley } 389*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexVecRestoreClosure(dmIn, section, localU, p, NULL, &coefficients)); 390*5f80ce2aSJacob Faibussowitsch if (dmAux) CHKERRQ(DMPlexVecRestoreClosure(dmAux, sectionAux, localA, p, NULL, &coefficientsAux)); 391b18799e0SMatthew G. Knepley PetscFunctionReturn(0); 392b18799e0SMatthew G. Knepley } 393b18799e0SMatthew G. Knepley 394a6e0b375SMatthew 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[], 395ef0bb6c7SMatthew G. Knepley PetscDualSpace sp[], PetscInt p, PetscTabulation *T, PetscTabulation *TAux, 3968c6c5593SMatthew G. Knepley DMBoundaryConditionType type, void (**funcs)(void), void **ctxs, PetscBool fieldActive[], PetscScalar values[]) 3978c6c5593SMatthew G. Knepley { 3988c6c5593SMatthew G. Knepley PetscFVCellGeom fvgeom; 3998c6c5593SMatthew G. Knepley PetscInt dim, dimEmbed; 4008c6c5593SMatthew G. Knepley PetscErrorCode ierr; 4018c6c5593SMatthew G. Knepley 4028c6c5593SMatthew G. Knepley PetscFunctionBeginHot; 403*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetDimension(dm, &dim)); 404*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetCoordinateDim(dm, &dimEmbed)); 405*5f80ce2aSJacob Faibussowitsch if (hasFV) CHKERRQ(DMPlexComputeCellGeometryFVM(dm, p, &fvgeom.volume, fvgeom.centroid, NULL)); 4068c6c5593SMatthew G. Knepley switch (type) { 4078c6c5593SMatthew G. Knepley case DM_BC_ESSENTIAL: 4088c6c5593SMatthew G. Knepley case DM_BC_NATURAL: 409*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMProjectPoint_Func_Private(dm, ds, dmIn, dsIn, time, fegeom, &fvgeom, isFE, sp, (PetscErrorCode (**)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *)) funcs, ctxs, values));break; 4108c6c5593SMatthew G. Knepley case DM_BC_ESSENTIAL_FIELD: 4118c6c5593SMatthew G. Knepley case DM_BC_NATURAL_FIELD: 412ef0bb6c7SMatthew G. Knepley ierr = DMProjectPoint_Field_Private(dm, ds, dmIn, encIn, dsIn, dmAux, encAux, dsAux, time, localU, localA, fegeom, sp, p, T, TAux, 4130c898c18SMatthew G. Knepley (void (**)(PetscInt, PetscInt, PetscInt, 4140c898c18SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 4150c898c18SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 416191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[])) funcs, ctxs, values);CHKERRQ(ierr);break; 417b18799e0SMatthew G. Knepley case DM_BC_ESSENTIAL_BD_FIELD: 418ef0bb6c7SMatthew G. Knepley ierr = DMProjectPoint_BdField_Private(dm, ds, dmIn, dsIn, dmAux, encAux, dsAux, time, localU, localA, fegeom, sp, p, T, TAux, 419b18799e0SMatthew G. Knepley (void (**)(PetscInt, PetscInt, PetscInt, 420b18799e0SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 421b18799e0SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 422b18799e0SMatthew G. Knepley PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[])) funcs, ctxs, values);CHKERRQ(ierr);break; 42398921bdaSJacob Faibussowitsch default: SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Unknown boundary condition type: %d", (int) type); 4248c6c5593SMatthew G. Knepley } 4258c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 4268c6c5593SMatthew G. Knepley } 4278c6c5593SMatthew G. Knepley 428df5c1128SToby Isaac static PetscErrorCode PetscDualSpaceGetAllPointsUnion(PetscInt Nf, PetscDualSpace *sp, PetscInt dim, void (**funcs)(void), PetscQuadrature *allPoints) 429df5c1128SToby Isaac { 430df5c1128SToby Isaac PetscReal *points; 431df5c1128SToby Isaac PetscInt f, numPoints; 432df5c1128SToby Isaac 433df5c1128SToby Isaac PetscFunctionBegin; 434df5c1128SToby Isaac numPoints = 0; 435df5c1128SToby Isaac for (f = 0; f < Nf; ++f) { 436df5c1128SToby Isaac if (funcs[f]) { 437df5c1128SToby Isaac PetscQuadrature fAllPoints; 438df5c1128SToby Isaac PetscInt fNumPoints; 439df5c1128SToby Isaac 440*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetAllData(sp[f],&fAllPoints, NULL)); 441*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetData(fAllPoints, NULL, NULL, &fNumPoints, NULL, NULL)); 442df5c1128SToby Isaac numPoints += fNumPoints; 443df5c1128SToby Isaac } 444df5c1128SToby Isaac } 445*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(dim*numPoints,&points)); 446df5c1128SToby Isaac numPoints = 0; 447df5c1128SToby Isaac for (f = 0; f < Nf; ++f) { 448df5c1128SToby Isaac if (funcs[f]) { 449df5c1128SToby Isaac PetscQuadrature fAllPoints; 45054ee0cceSMatthew G. Knepley PetscInt qdim, fNumPoints, q; 451df5c1128SToby Isaac const PetscReal *fPoints; 452df5c1128SToby Isaac 453*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetAllData(sp[f],&fAllPoints, NULL)); 454*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetData(fAllPoints, &qdim, NULL, &fNumPoints, &fPoints, NULL)); 4552c71b3e2SJacob Faibussowitsch PetscCheckFalse(qdim != dim,PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Spatial dimension %D for dual basis does not match input dimension %D", qdim, dim); 456df5c1128SToby Isaac for (q = 0; q < fNumPoints*dim; ++q) points[numPoints*dim+q] = fPoints[q]; 457df5c1128SToby Isaac numPoints += fNumPoints; 458df5c1128SToby Isaac } 459df5c1128SToby Isaac } 460*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureCreate(PETSC_COMM_SELF,allPoints)); 461*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureSetData(*allPoints,dim,0,numPoints,points,NULL)); 462df5c1128SToby Isaac PetscFunctionReturn(0); 463df5c1128SToby Isaac } 464df5c1128SToby Isaac 4655f15299fSJeremy L Thompson /*@C 4665f15299fSJeremy L Thompson DMGetFirstLabeledPoint - Find first labeled point p_o in odm such that the corresponding point p in dm has the specified height. Return p and the corresponding ds. 4675f15299fSJeremy L Thompson 4685f15299fSJeremy L Thompson Input Parameters: 4695f15299fSJeremy L Thompson dm - the DM 4705f15299fSJeremy L Thompson odm - the enclosing DM 4715f15299fSJeremy L Thompson label - label for DM domain, or NULL for whole domain 4725f15299fSJeremy L Thompson numIds - the number of ids 4735f15299fSJeremy L Thompson ids - An array of the label ids in sequence for the domain 4745f15299fSJeremy L Thompson height - Height of target cells in DMPlex topology 4755f15299fSJeremy L Thompson 4765f15299fSJeremy L Thompson Output Parameters: 4775f15299fSJeremy L Thompson point - the first labeled point 4785f15299fSJeremy L Thompson ds - the ds corresponding to the first labeled point 4795f15299fSJeremy L Thompson 4805f15299fSJeremy L Thompson Level: developer 481817da375SSatish Balay @*/ 4825f15299fSJeremy L Thompson PetscErrorCode DMGetFirstLabeledPoint(DM dm, DM odm, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt height, PetscInt *point, PetscDS *ds) 483e5e52638SMatthew G. Knepley { 484a6e0b375SMatthew G. Knepley DM plex; 485a6e0b375SMatthew G. Knepley DMEnclosureType enc; 486e9f0ba4eSJed Brown PetscInt ls = -1; 487e5e52638SMatthew G. Knepley 488e5e52638SMatthew G. Knepley PetscFunctionBegin; 4895f15299fSJeremy L Thompson if (point) *point = -1; 490e5e52638SMatthew G. Knepley if (!label) PetscFunctionReturn(0); 491*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetEnclosureRelation(dm, odm, &enc)); 492*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMConvert(dm, DMPLEX, &plex)); 493e9f0ba4eSJed Brown for (PetscInt i = 0; i < numIds; ++i) { 494e9f0ba4eSJed Brown IS labelIS; 495e9f0ba4eSJed Brown PetscInt num_points, pStart, pEnd; 496*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMLabelGetStratumIS(label, ids[i], &labelIS)); 497e9f0ba4eSJed Brown if (!labelIS) continue; /* No points with that id on this process */ 498*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetHeightStratum(plex, height, &pStart, &pEnd)); 499*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetSize(labelIS, &num_points)); 500e9f0ba4eSJed Brown if (num_points) { 501e5e52638SMatthew G. Knepley const PetscInt *points; 502*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetIndices(labelIS, &points)); 503e9f0ba4eSJed Brown for (PetscInt i=0; i<num_points; i++) { 504e9f0ba4eSJed Brown PetscInt point; 505*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetEnclosurePoint(dm, odm, enc, points[i], &point)); 506e9f0ba4eSJed Brown if (pStart <= point && point < pEnd) { 507a6e0b375SMatthew G. Knepley ls = point; 508*5f80ce2aSJacob Faibussowitsch if (ds) CHKERRQ(DMGetCellDS(dm, ls, ds)); 509e5e52638SMatthew G. Knepley } 510e9f0ba4eSJed Brown } 511*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISRestoreIndices(labelIS, &points)); 512e9f0ba4eSJed Brown } 513*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&labelIS)); 514e5e52638SMatthew G. Knepley if (ls >= 0) break; 515e5e52638SMatthew G. Knepley } 5165f15299fSJeremy L Thompson if (point) *point = ls; 517*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDestroy(&plex)); 518e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 519e5e52638SMatthew G. Knepley } 520e5e52638SMatthew G. Knepley 5210de51b56SMatthew G. Knepley /* 5220de51b56SMatthew G. Knepley This function iterates over a manifold, and interpolates the input function/field using the basis provided by the DS in our DM 5230de51b56SMatthew G. Knepley 5240de51b56SMatthew G. Knepley There are several different scenarios: 5250de51b56SMatthew G. Knepley 5260de51b56SMatthew G. Knepley 1) Volumetric mesh with volumetric auxiliary data 5270de51b56SMatthew G. Knepley 5280de51b56SMatthew G. Knepley Here minHeight=0 since we loop over cells. 5290de51b56SMatthew G. Knepley 5300de51b56SMatthew G. Knepley 2) Boundary mesh with boundary auxiliary data 5310de51b56SMatthew G. Knepley 5320de51b56SMatthew 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. 5330de51b56SMatthew G. Knepley 5340de51b56SMatthew G. Knepley 3) Volumetric mesh with boundary auxiliary data 5350de51b56SMatthew G. Knepley 5360de51b56SMatthew 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. 5370de51b56SMatthew G. Knepley 538636b9322SMatthew G. Knepley 4) Volumetric input mesh with boundary output mesh 539636b9322SMatthew G. Knepley 540636b9322SMatthew G. Knepley Here we must get a subspace for the input DS 541636b9322SMatthew G. Knepley 5420de51b56SMatthew G. Knepley The maxHeight is used to support enforcement of constraints in DMForest. 5430de51b56SMatthew G. Knepley 5440de51b56SMatthew G. Knepley If localU is given and not equal to localX, we call DMPlexInsertBoundaryValues() to complete it. 5450de51b56SMatthew G. Knepley 5460de51b56SMatthew 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. 5470de51b56SMatthew 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 5485f790a90SMatthew G. Knepley is for the volumetric mesh, but we are iterating over a surface, then the effective height is nonzero. When the effective height is nonzero, we need to extract 5490de51b56SMatthew G. Knepley dual spaces for the boundary from our input spaces. 5500de51b56SMatthew G. Knepley - After extracting all quadrature points, we tabulate the input fields and auxiliary fields on them. 5510de51b56SMatthew G. Knepley 5520de51b56SMatthew G. Knepley We check that the #dof(closure(p)) == #dual basis functionals(p) for a representative p in the iteration 5530de51b56SMatthew G. Knepley 5540de51b56SMatthew 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. 5550de51b56SMatthew G. Knepley */ 55646fa42a0SMatthew G. Knepley static PetscErrorCode DMProjectLocal_Generic_Plex(DM dm, PetscReal time, Vec localU, 5571c531cf8SMatthew G. Knepley PetscInt Ncc, const PetscInt comps[], DMLabel label, PetscInt numIds, const PetscInt ids[], 5588c6c5593SMatthew G. Knepley DMBoundaryConditionType type, void (**funcs)(void), void **ctxs, 5598c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 5608c6c5593SMatthew G. Knepley { 561a6e0b375SMatthew G. Knepley DM plex, dmIn, plexIn, dmAux = NULL, plexAux = NULL, tdm; 562a6e0b375SMatthew G. Knepley DMEnclosureType encIn, encAux; 563a6e0b375SMatthew G. Knepley PetscDS ds = NULL, dsIn = NULL, dsAux = NULL; 564ca3d3a14SMatthew G. Knepley Vec localA = NULL, tv; 565aa0eca99SMatthew G. Knepley IS fieldIS; 56647923291SMatthew G. Knepley PetscSection section; 567636b9322SMatthew G. Knepley PetscDualSpace *sp, *cellsp, *spIn, *cellspIn; 568ef0bb6c7SMatthew G. Knepley PetscTabulation *T = NULL, *TAux = NULL; 5698c6c5593SMatthew G. Knepley PetscInt *Nc; 570636b9322SMatthew G. Knepley PetscInt dim, dimEmbed, depth, htInc = 0, htIncIn = 0, htIncAux = 0, minHeight, maxHeight, h, regionNum, Nf, NfIn, NfAux = 0, NfTot, f; 5715fedec97SMatthew G. Knepley PetscBool *isFE, hasFE = PETSC_FALSE, hasFV = PETSC_FALSE, isCohesive = PETSC_FALSE, transform; 572c330f8ffSToby Isaac DMField coordField; 573c330f8ffSToby Isaac DMLabel depthLabel; 574c330f8ffSToby Isaac PetscQuadrature allPoints = NULL; 57547923291SMatthew G. Knepley PetscErrorCode ierr; 57647923291SMatthew G. Knepley 57747923291SMatthew G. Knepley PetscFunctionBegin; 578*5f80ce2aSJacob Faibussowitsch if (localU) CHKERRQ(VecGetDM(localU, &dmIn)); 579a6e0b375SMatthew G. Knepley else {dmIn = dm;} 580*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetAuxiliaryVec(dm, label, numIds ? ids[0] : 0, 0, &localA)); 581*5f80ce2aSJacob Faibussowitsch if (localA) CHKERRQ(VecGetDM(localA, &dmAux)); else {dmAux = NULL;} 582*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMConvert(dm, DMPLEX, &plex)); 583*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMConvert(dmIn, DMPLEX, &plexIn)); 584*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetEnclosureRelation(dmIn, dm, &encIn)); 585*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetEnclosureRelation(dmAux, dm, &encAux)); 586*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetDimension(dm, &dim)); 587*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetVTKCellHeight(plex, &minHeight)); 588*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetBasisTransformDM_Internal(dm, &tdm)); 589*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetBasisTransformVec_Internal(dm, &tv)); 590*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMHasBasisTransform(dm, &transform)); 5910de51b56SMatthew G. Knepley /* Auxiliary information can only be used with interpolation of field functions */ 592a6e0b375SMatthew G. Knepley if (dmAux) { 593*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMConvert(dmAux, DMPLEX, &plexAux)); 594a6e0b375SMatthew G. Knepley if (type == DM_BC_ESSENTIAL_FIELD || type == DM_BC_ESSENTIAL_BD_FIELD || type == DM_BC_NATURAL_FIELD) { 5952c71b3e2SJacob Faibussowitsch PetscCheckFalse(!localA,PETSC_COMM_SELF, PETSC_ERR_USER, "Missing localA vector"); 596636b9322SMatthew G. Knepley } 597636b9322SMatthew G. Knepley } 598636b9322SMatthew G. Knepley /* Determine height for iteration of all meshes */ 599636b9322SMatthew G. Knepley { 600636b9322SMatthew G. Knepley DMPolytopeType ct, ctIn, ctAux; 601636b9322SMatthew G. Knepley PetscInt minHeightIn, minHeightAux, lStart, pStart, pEnd, p, pStartIn, pStartAux; 602636b9322SMatthew G. Knepley PetscInt dim = -1, dimIn, dimAux; 60388aca1feSMatthew G. Knepley 604*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetSimplexOrBoxCells(plex, minHeight, &pStart, &pEnd)); 605636b9322SMatthew G. Knepley if (pEnd > pStart) { 606*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetFirstLabeledPoint(dm, dm, label, numIds, ids, minHeight, &lStart, NULL)); 607636b9322SMatthew G. Knepley p = lStart < 0 ? pStart : lStart; 608*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetCellType(plex, p, &ct)); 609636b9322SMatthew G. Knepley dim = DMPolytopeTypeGetDim(ct); 610*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetVTKCellHeight(plexIn, &minHeightIn)); 611*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetSimplexOrBoxCells(plexIn, minHeightIn, &pStartIn, NULL)); 612*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetCellType(plexIn, pStartIn, &ctIn)); 613636b9322SMatthew G. Knepley dimIn = DMPolytopeTypeGetDim(ctIn); 614636b9322SMatthew G. Knepley if (dmAux) { 615*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetVTKCellHeight(plexAux, &minHeightAux)); 616*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetSimplexOrBoxCells(plexAux, minHeightAux, &pStartAux, NULL)); 617*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetCellType(plexAux, pStartAux, &ctAux)); 618636b9322SMatthew G. Knepley dimAux = DMPolytopeTypeGetDim(ctAux); 619636b9322SMatthew G. Knepley } else dimAux = dim; 620e39fcb4eSStefano Zampini } 621636b9322SMatthew G. Knepley if (dim < 0) { 622636b9322SMatthew G. Knepley DMLabel spmap = NULL, spmapIn = NULL, spmapAux = NULL; 623636b9322SMatthew G. Knepley 624636b9322SMatthew G. Knepley /* Fall back to determination based on being a submesh */ 625*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetSubpointMap(plex, &spmap)); 626*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetSubpointMap(plexIn, &spmapIn)); 627*5f80ce2aSJacob Faibussowitsch if (plexAux) CHKERRQ(DMPlexGetSubpointMap(plexAux, &spmapAux)); 628636b9322SMatthew G. Knepley dim = spmap ? 1 : 0; 629636b9322SMatthew G. Knepley dimIn = spmapIn ? 1 : 0; 630636b9322SMatthew G. Knepley dimAux = spmapAux ? 1 : 0; 63188aca1feSMatthew G. Knepley } 632636b9322SMatthew G. Knepley { 633636b9322SMatthew G. Knepley PetscInt dimProj = PetscMin(PetscMin(dim, dimIn), dimAux); 634636b9322SMatthew G. Knepley 6352c71b3e2SJacob Faibussowitsch PetscCheckFalse(PetscAbsInt(dimProj - dim) > 1 || PetscAbsInt(dimProj - dimIn) > 1 || PetscAbsInt(dimProj - dimAux) > 1,PETSC_COMM_SELF, PETSC_ERR_SUP, "Do not currently support differences of more than 1 in dimension"); 636636b9322SMatthew G. Knepley if (dimProj < dim) minHeight = 1; 637636b9322SMatthew G. Knepley htInc = dim - dimProj; 638636b9322SMatthew G. Knepley htIncIn = dimIn - dimProj; 639636b9322SMatthew G. Knepley htIncAux = dimAux - dimProj; 6400de51b56SMatthew G. Knepley } 641a6e0b375SMatthew G. Knepley } 642*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetDepth(plex, &depth)); 643*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetDepthLabel(plex, &depthLabel)); 644*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetMaxProjectionHeight(plex, &maxHeight)); 6452af58022SMatthew G. Knepley maxHeight = PetscMax(maxHeight, minHeight); 6462c71b3e2SJacob Faibussowitsch PetscCheck(maxHeight >= 0 && maxHeight <= dim,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Maximum projection height %D not in [0, %D)", maxHeight, dim); 647*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetFirstLabeledPoint(dm, dm, label, numIds, ids, 0, NULL, &ds)); 648*5f80ce2aSJacob Faibussowitsch if (!ds) CHKERRQ(DMGetDS(dm, &ds)); 649*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetFirstLabeledPoint(dmIn, dm, label, numIds, ids, 0, NULL, &dsIn)); 650*5f80ce2aSJacob Faibussowitsch if (!dsIn) CHKERRQ(DMGetDS(dmIn, &dsIn)); 651*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(ds, &Nf)); 652*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(dsIn, &NfIn)); 653*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetNumFields(dm, &NfTot)); 654*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMFindRegionNum(dm, ds, ®ionNum)); 655*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetRegionNumDS(dm, regionNum, NULL, &fieldIS, NULL)); 656*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSIsCohesive(ds, &isCohesive)); 657*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetCoordinateDim(dm, &dimEmbed)); 658*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetLocalSection(dm, §ion)); 6590c898c18SMatthew G. Knepley if (dmAux) { 660*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetDS(dmAux, &dsAux)); 661*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(dsAux, &NfAux)); 6620c898c18SMatthew G. Knepley } 663*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponents(ds, &Nc)); 664*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc3(Nf, &isFE, Nf, &sp, NfIn, &spIn)); 665*5f80ce2aSJacob Faibussowitsch if (maxHeight > 0) CHKERRQ(PetscMalloc2(Nf, &cellsp, NfIn, &cellspIn)); 666636b9322SMatthew G. Knepley else {cellsp = sp; cellspIn = spIn;} 667*5f80ce2aSJacob Faibussowitsch if (localU && localU != localX) CHKERRQ(DMPlexInsertBoundaryValues(plex, PETSC_TRUE, localU, time, NULL, NULL, NULL)); 6688c6c5593SMatthew G. Knepley /* Get cell dual spaces */ 66947923291SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 670665f567fSMatthew G. Knepley PetscDiscType disctype; 67147923291SMatthew G. Knepley 672*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscType_Internal(ds, f, &disctype)); 673665f567fSMatthew G. Knepley if (disctype == PETSC_DISC_FE) { 674665f567fSMatthew G. Knepley PetscFE fe; 67547923291SMatthew G. Knepley 67647923291SMatthew G. Knepley isFE[f] = PETSC_TRUE; 677665f567fSMatthew G. Knepley hasFE = PETSC_TRUE; 678*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(ds, f, (PetscObject *) &fe)); 679*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetDualSpace(fe, &cellsp[f])); 680665f567fSMatthew G. Knepley } else if (disctype == PETSC_DISC_FV) { 681665f567fSMatthew G. Knepley PetscFV fv; 68247923291SMatthew G. Knepley 68347923291SMatthew G. Knepley isFE[f] = PETSC_FALSE; 684665f567fSMatthew G. Knepley hasFV = PETSC_TRUE; 685*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(ds, f, (PetscObject *) &fv)); 686*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVGetDualSpace(fv, &cellsp[f])); 687665f567fSMatthew G. Knepley } else { 688665f567fSMatthew G. Knepley isFE[f] = PETSC_FALSE; 689665f567fSMatthew G. Knepley cellsp[f] = NULL; 690665f567fSMatthew G. Knepley } 69147923291SMatthew G. Knepley } 692636b9322SMatthew G. Knepley for (f = 0; f < NfIn; ++f) { 693636b9322SMatthew G. Knepley PetscDiscType disctype; 694636b9322SMatthew G. Knepley 695*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscType_Internal(dsIn, f, &disctype)); 696636b9322SMatthew G. Knepley if (disctype == PETSC_DISC_FE) { 697636b9322SMatthew G. Knepley PetscFE fe; 698636b9322SMatthew G. Knepley 699*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(dsIn, f, (PetscObject *) &fe)); 700*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetDualSpace(fe, &cellspIn[f])); 701636b9322SMatthew G. Knepley } else if (disctype == PETSC_DISC_FV) { 702636b9322SMatthew G. Knepley PetscFV fv; 703636b9322SMatthew G. Knepley 704*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(dsIn, f, (PetscObject *) &fv)); 705*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFVGetDualSpace(fv, &cellspIn[f])); 706636b9322SMatthew G. Knepley } else { 707636b9322SMatthew G. Knepley cellspIn[f] = NULL; 708636b9322SMatthew G. Knepley } 709636b9322SMatthew G. Knepley } 710*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetCoordinateField(dm,&coordField)); 711636b9322SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 712636b9322SMatthew G. Knepley if (!htInc) {sp[f] = cellsp[f];} 713*5f80ce2aSJacob Faibussowitsch else CHKERRQ(PetscDualSpaceGetHeightSubspace(cellsp[f], htInc, &sp[f])); 714636b9322SMatthew G. Knepley } 715ece3a9fcSMatthew G. Knepley if (type == DM_BC_ESSENTIAL_FIELD || type == DM_BC_ESSENTIAL_BD_FIELD || type == DM_BC_NATURAL_FIELD) { 71674fc349aSMatthew G. Knepley PetscFE fem, subfem; 717665f567fSMatthew G. Knepley PetscDiscType disctype; 7184a3e9fdbSToby Isaac const PetscReal *points; 7194a3e9fdbSToby Isaac PetscInt numPoints; 7200c898c18SMatthew G. Knepley 7212c71b3e2SJacob Faibussowitsch PetscCheckFalse(maxHeight > minHeight,PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Field projection not supported for face interpolation"); 722*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetAllPointsUnion(Nf, sp, dim-htInc, funcs, &allPoints)); 723*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetData(allPoints, NULL, NULL, &numPoints, &points, NULL)); 724*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc2(NfIn, &T, NfAux, &TAux)); 725a6e0b375SMatthew G. Knepley for (f = 0; f < NfIn; ++f) { 726636b9322SMatthew G. Knepley if (!htIncIn) {spIn[f] = cellspIn[f];} 727*5f80ce2aSJacob Faibussowitsch else CHKERRQ(PetscDualSpaceGetHeightSubspace(cellspIn[f], htIncIn, &spIn[f])); 728636b9322SMatthew G. Knepley 729*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscType_Internal(dsIn, f, &disctype)); 730665f567fSMatthew G. Knepley if (disctype != PETSC_DISC_FE) continue; 731*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(dsIn, f, (PetscObject *) &fem)); 732636b9322SMatthew G. Knepley if (!htIncIn) {subfem = fem;} 733*5f80ce2aSJacob Faibussowitsch else CHKERRQ(PetscFEGetHeightSubspace(fem, htIncIn, &subfem)); 734*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFECreateTabulation(subfem, 1, numPoints, points, 1, &T[f])); 7350c898c18SMatthew G. Knepley } 7360c898c18SMatthew G. Knepley for (f = 0; f < NfAux; ++f) { 737*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscType_Internal(dsAux, f, &disctype)); 738665f567fSMatthew G. Knepley if (disctype != PETSC_DISC_FE) continue; 739*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(dsAux, f, (PetscObject *) &fem)); 740636b9322SMatthew G. Knepley if (!htIncAux) {subfem = fem;} 741*5f80ce2aSJacob Faibussowitsch else CHKERRQ(PetscFEGetHeightSubspace(fem, htIncAux, &subfem)); 742*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFECreateTabulation(subfem, 1, numPoints, points, 1, &TAux[f])); 7430c898c18SMatthew G. Knepley } 7440c898c18SMatthew G. Knepley } 74547923291SMatthew G. Knepley /* Note: We make no attempt to optimize for height. Higher height things just overwrite the lower height results. */ 7462af58022SMatthew G. Knepley for (h = minHeight; h <= maxHeight; h++) { 747636b9322SMatthew G. Knepley PetscInt hEff = h - minHeight + htInc; 748636b9322SMatthew G. Knepley PetscInt hEffIn = h - minHeight + htIncIn; 749636b9322SMatthew G. Knepley PetscInt hEffAux = h - minHeight + htIncAux; 750a6e0b375SMatthew G. Knepley PetscDS dsEff = ds; 751636b9322SMatthew G. Knepley PetscDS dsEffIn = dsIn; 752636b9322SMatthew G. Knepley PetscDS dsEffAux = dsAux; 7538c6c5593SMatthew G. Knepley PetscScalar *values; 754b7260050SToby Isaac PetscBool *fieldActive; 755b7260050SToby Isaac PetscInt maxDegree; 756e5e52638SMatthew G. Knepley PetscInt pStart, pEnd, p, lStart, spDim, totDim, numValues; 757c330f8ffSToby Isaac IS heightIS; 7588c6c5593SMatthew G. Knepley 759636b9322SMatthew G. Knepley if (h > minHeight) { 760*5f80ce2aSJacob Faibussowitsch for (f = 0; f < Nf; ++f) CHKERRQ(PetscDualSpaceGetHeightSubspace(cellsp[f], hEff, &sp[f])); 761636b9322SMatthew G. Knepley } 762*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetSimplexOrBoxCells(plex, h, &pStart, &pEnd)); 763*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetFirstLabeledPoint(dm, dm, label, numIds, ids, h, &lStart, NULL)); 764*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMLabelGetStratumIS(depthLabel, depth - h, &heightIS)); 765c330f8ffSToby Isaac if (pEnd <= pStart) { 766*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&heightIS)); 767c330f8ffSToby Isaac continue; 768c330f8ffSToby Isaac } 76947923291SMatthew G. Knepley /* Compute totDim, the number of dofs in the closure of a point at this height */ 77047923291SMatthew G. Knepley totDim = 0; 77147923291SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 7725fedec97SMatthew G. Knepley PetscBool cohesive; 7735fedec97SMatthew G. Knepley 774665f567fSMatthew G. Knepley if (!sp[f]) continue; 775*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetCohesive(ds, f, &cohesive)); 776*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDimension(sp[f], &spDim)); 7779c3cf19fSMatthew G. Knepley totDim += spDim; 7785fedec97SMatthew G. Knepley if (isCohesive && !cohesive) totDim += spDim; 77947923291SMatthew G. Knepley } 780636b9322SMatthew G. Knepley p = lStart < 0 ? pStart : lStart; 781*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexVecGetClosure(plex, section, localX, p, &numValues, NULL)); 7822c71b3e2SJacob Faibussowitsch PetscCheckFalse(numValues != totDim,PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "The output section point (%D) closure size %D != dual space dimension %D at height %D in [%D, %D]", p, numValues, totDim, h, minHeight, maxHeight); 783c330f8ffSToby Isaac if (!totDim) { 784*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&heightIS)); 785c330f8ffSToby Isaac continue; 786c330f8ffSToby Isaac } 787*5f80ce2aSJacob Faibussowitsch if (htInc) CHKERRQ(PetscDSGetHeightSubspace(ds, hEff, &dsEff)); 788636b9322SMatthew G. Knepley /* Compute totDimIn, the number of dofs in the closure of a point at this height */ 789636b9322SMatthew G. Knepley if (localU) { 790636b9322SMatthew G. Knepley PetscInt totDimIn, pIn, numValuesIn; 791636b9322SMatthew G. Knepley 792636b9322SMatthew G. Knepley totDimIn = 0; 793636b9322SMatthew G. Knepley for (f = 0; f < NfIn; ++f) { 7945fedec97SMatthew G. Knepley PetscBool cohesive; 7955fedec97SMatthew G. Knepley 796636b9322SMatthew G. Knepley if (!spIn[f]) continue; 797*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetCohesive(dsIn, f, &cohesive)); 798*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDimension(spIn[f], &spDim)); 799636b9322SMatthew G. Knepley totDimIn += spDim; 8005fedec97SMatthew G. Knepley if (isCohesive && !cohesive) totDimIn += spDim; 801636b9322SMatthew G. Knepley } 802*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetEnclosurePoint(dmIn, dm, encIn, lStart < 0 ? pStart : lStart, &pIn)); 803*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexVecGetClosure(plexIn, NULL, localU, pIn, &numValuesIn, NULL)); 8042c71b3e2SJacob Faibussowitsch PetscCheckFalse(numValuesIn != totDimIn,PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "The input section point (%D) closure size %D != dual space dimension %D at height %D", pIn, numValuesIn, totDimIn, htIncIn); 805*5f80ce2aSJacob Faibussowitsch if (htIncIn) CHKERRQ(PetscDSGetHeightSubspace(dsIn, hEffIn, &dsEffIn)); 806636b9322SMatthew G. Knepley } 807*5f80ce2aSJacob Faibussowitsch if (htIncAux) CHKERRQ(PetscDSGetHeightSubspace(dsAux, hEffAux, &dsEffAux)); 80847923291SMatthew G. Knepley /* Loop over points at this height */ 809*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetWorkArray(dm, numValues, MPIU_SCALAR, &values)); 810*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetWorkArray(dm, NfTot, MPI_INT, &fieldActive)); 811aa0eca99SMatthew G. Knepley { 812aa0eca99SMatthew G. Knepley const PetscInt *fields; 813aa0eca99SMatthew G. Knepley 814*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetIndices(fieldIS, &fields)); 815aa0eca99SMatthew G. Knepley for (f = 0; f < NfTot; ++f) {fieldActive[f] = PETSC_FALSE;} 816aa0eca99SMatthew G. Knepley for (f = 0; f < Nf; ++f) {fieldActive[fields[f]] = (funcs[f] && sp[f]) ? PETSC_TRUE : PETSC_FALSE;} 817*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISRestoreIndices(fieldIS, &fields)); 818aa0eca99SMatthew G. Knepley } 8198c6c5593SMatthew G. Knepley if (label) { 8208c6c5593SMatthew G. Knepley PetscInt i; 82147923291SMatthew G. Knepley 82247923291SMatthew G. Knepley for (i = 0; i < numIds; ++i) { 823c330f8ffSToby Isaac IS pointIS, isectIS; 82447923291SMatthew G. Knepley const PetscInt *points; 8258c6c5593SMatthew G. Knepley PetscInt n; 826c330f8ffSToby Isaac PetscFEGeom *fegeom = NULL, *chunkgeom = NULL; 827c330f8ffSToby Isaac PetscQuadrature quad = NULL; 82847923291SMatthew G. Knepley 829*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMLabelGetStratumIS(label, ids[i], &pointIS)); 83047923291SMatthew G. Knepley if (!pointIS) continue; /* No points with that id on this process */ 831*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISIntersect(pointIS,heightIS,&isectIS)); 832*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&pointIS)); 833c330f8ffSToby Isaac if (!isectIS) continue; 834*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetLocalSize(isectIS, &n)); 835*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetIndices(isectIS, &points)); 836*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMFieldGetDegree(coordField,isectIS,NULL,&maxDegree)); 837b7260050SToby Isaac if (maxDegree <= 1) { 838*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMFieldCreateDefaultQuadrature(coordField,isectIS,&quad)); 839c330f8ffSToby Isaac } 840c330f8ffSToby Isaac if (!quad) { 841c330f8ffSToby Isaac if (!h && allPoints) { 842c330f8ffSToby Isaac quad = allPoints; 843c330f8ffSToby Isaac allPoints = NULL; 844c330f8ffSToby Isaac } else { 845*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetAllPointsUnion(Nf,sp,isCohesive ? dim-htInc-1 : dim-htInc,funcs,&quad)); 846c330f8ffSToby Isaac } 847c330f8ffSToby Isaac } 848*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMFieldCreateFEGeom(coordField, isectIS, quad, (htInc && h == minHeight) ? PETSC_TRUE : PETSC_FALSE, &fegeom)); 84947923291SMatthew G. Knepley for (p = 0; p < n; ++p) { 85047923291SMatthew G. Knepley const PetscInt point = points[p]; 85147923291SMatthew G. Knepley 852*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(values, numValues)); 853*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGeomGetChunk(fegeom,p,p+1,&chunkgeom)); 854*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexSetActivePoint(dm, point)); 855636b9322SMatthew G. Knepley ierr = DMProjectPoint_Private(dm, dsEff, plexIn, encIn, dsEffIn, plexAux, encAux, dsEffAux, chunkgeom, htInc, time, localU, localA, hasFE, hasFV, isFE, sp, point, T, TAux, type, funcs, ctxs, fieldActive, values); 85647923291SMatthew G. Knepley if (ierr) { 857*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreWorkArray(dm, numValues, MPIU_SCALAR, &values)); 858*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreWorkArray(dm, Nf, MPI_INT, &fieldActive)); 85947923291SMatthew G. Knepley CHKERRQ(ierr); 86047923291SMatthew G. Knepley } 861*5f80ce2aSJacob Faibussowitsch if (transform) CHKERRQ(DMPlexBasisTransformPoint_Internal(plex, tdm, tv, point, fieldActive, PETSC_FALSE, values)); 862*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexVecSetFieldClosure_Internal(plex, section, localX, fieldActive, point, Ncc, comps, label, ids[i], values, mode)); 86347923291SMatthew G. Knepley } 864*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGeomRestoreChunk(fegeom,p,p+1,&chunkgeom)); 865*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGeomDestroy(&fegeom)); 866*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureDestroy(&quad)); 867*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISRestoreIndices(isectIS, &points)); 868*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&isectIS)); 86947923291SMatthew G. Knepley } 8708c6c5593SMatthew G. Knepley } else { 871c330f8ffSToby Isaac PetscFEGeom *fegeom = NULL, *chunkgeom = NULL; 872c330f8ffSToby Isaac PetscQuadrature quad = NULL; 873c330f8ffSToby Isaac IS pointIS; 874c330f8ffSToby Isaac 875*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISCreateStride(PETSC_COMM_SELF,pEnd-pStart,pStart,1,&pointIS)); 876*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMFieldGetDegree(coordField,pointIS,NULL,&maxDegree)); 877b7260050SToby Isaac if (maxDegree <= 1) { 878*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMFieldCreateDefaultQuadrature(coordField,pointIS,&quad)); 879c330f8ffSToby Isaac } 880c330f8ffSToby Isaac if (!quad) { 881c330f8ffSToby Isaac if (!h && allPoints) { 882c330f8ffSToby Isaac quad = allPoints; 883c330f8ffSToby Isaac allPoints = NULL; 884c330f8ffSToby Isaac } else { 885*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetAllPointsUnion(Nf, sp, dim-htInc, funcs, &quad)); 886c330f8ffSToby Isaac } 887c330f8ffSToby Isaac } 888*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMFieldCreateFEGeom(coordField, pointIS, quad, (htInc && h == minHeight) ? PETSC_TRUE : PETSC_FALSE, &fegeom)); 8898c6c5593SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 890*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(values, numValues)); 891*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGeomGetChunk(fegeom,p-pStart,p-pStart+1,&chunkgeom)); 892*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexSetActivePoint(dm, p)); 893636b9322SMatthew G. Knepley ierr = DMProjectPoint_Private(dm, dsEff, plexIn, encIn, dsEffIn, plexAux, encAux, dsEffAux, chunkgeom, htInc, time, localU, localA, hasFE, hasFV, isFE, sp, p, T, TAux, type, funcs, ctxs, fieldActive, values); 8948c6c5593SMatthew G. Knepley if (ierr) { 895*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreWorkArray(dm, numValues, MPIU_SCALAR, &values)); 896*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreWorkArray(dm, Nf, MPI_INT, &fieldActive)); 8978c6c5593SMatthew G. Knepley CHKERRQ(ierr); 8988c6c5593SMatthew G. Knepley } 899*5f80ce2aSJacob Faibussowitsch if (transform) CHKERRQ(DMPlexBasisTransformPoint_Internal(plex, tdm, tv, p, fieldActive, PETSC_FALSE, values)); 900*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexVecSetFieldClosure_Internal(plex, section, localX, fieldActive, p, Ncc, comps, NULL, -1, values, mode)); 9018c6c5593SMatthew G. Knepley } 902*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGeomRestoreChunk(fegeom,p-pStart,pStart-p+1,&chunkgeom)); 903*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGeomDestroy(&fegeom)); 904*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureDestroy(&quad)); 905*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&pointIS)); 9068c6c5593SMatthew G. Knepley } 907*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&heightIS)); 908*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreWorkArray(dm, numValues, MPIU_SCALAR, &values)); 909*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreWorkArray(dm, Nf, MPI_INT, &fieldActive)); 91047923291SMatthew G. Knepley } 9118c6c5593SMatthew G. Knepley /* Cleanup */ 912ece3a9fcSMatthew G. Knepley if (type == DM_BC_ESSENTIAL_FIELD || type == DM_BC_ESSENTIAL_BD_FIELD || type == DM_BC_NATURAL_FIELD) { 913*5f80ce2aSJacob Faibussowitsch for (f = 0; f < NfIn; ++f) CHKERRQ(PetscTabulationDestroy(&T[f])); 914*5f80ce2aSJacob Faibussowitsch for (f = 0; f < NfAux; ++f) CHKERRQ(PetscTabulationDestroy(&TAux[f])); 915*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree2(T, TAux)); 9160c898c18SMatthew G. Knepley } 917*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureDestroy(&allPoints)); 918*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree3(isFE, sp, spIn)); 919*5f80ce2aSJacob Faibussowitsch if (maxHeight > 0) CHKERRQ(PetscFree2(cellsp, cellspIn)); 920*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDestroy(&plex)); 921*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDestroy(&plexIn)); 922*5f80ce2aSJacob Faibussowitsch if (dmAux) CHKERRQ(DMDestroy(&plexAux)); 9238c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 92447923291SMatthew G. Knepley } 9258c6c5593SMatthew G. Knepley 9268c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFunctionLocal_Plex(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX) 9278c6c5593SMatthew G. Knepley { 9288c6c5593SMatthew G. Knepley PetscFunctionBegin; 929*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMProjectLocal_Generic_Plex(dm, time, NULL, 0, NULL, NULL, 0, NULL, DM_BC_ESSENTIAL, (void (**)(void)) funcs, ctxs, mode, localX)); 9308c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 9318c6c5593SMatthew G. Knepley } 9328c6c5593SMatthew G. Knepley 9331c531cf8SMatthew 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) 9348c6c5593SMatthew G. Knepley { 9358c6c5593SMatthew G. Knepley PetscFunctionBegin; 936*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMProjectLocal_Generic_Plex(dm, time, NULL, Ncc, comps, label, numIds, ids, DM_BC_ESSENTIAL, (void (**)(void)) funcs, ctxs, mode, localX)); 93747923291SMatthew G. Knepley PetscFunctionReturn(0); 93847923291SMatthew G. Knepley } 93947923291SMatthew G. Knepley 9408c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFieldLocal_Plex(DM dm, PetscReal time, Vec localU, 94147923291SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 94247923291SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 94347923291SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 944191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 94547923291SMatthew G. Knepley InsertMode mode, Vec localX) 94647923291SMatthew G. Knepley { 94747923291SMatthew G. Knepley PetscFunctionBegin; 948*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMProjectLocal_Generic_Plex(dm, time, localU, 0, NULL, NULL, 0, NULL, DM_BC_ESSENTIAL_FIELD, (void (**)(void)) funcs, NULL, mode, localX)); 9498c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 95047923291SMatthew G. Knepley } 95147923291SMatthew G. Knepley 9521c531cf8SMatthew G. Knepley PetscErrorCode DMProjectFieldLabelLocal_Plex(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Ncc, const PetscInt comps[], Vec localU, 9538c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 9548c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 9558c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 956191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 9578c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 9588c6c5593SMatthew G. Knepley { 9598c6c5593SMatthew G. Knepley PetscFunctionBegin; 960*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMProjectLocal_Generic_Plex(dm, time, localU, Ncc, comps, label, numIds, ids, DM_BC_ESSENTIAL_FIELD, (void (**)(void)) funcs, NULL, mode, localX)); 96147923291SMatthew G. Knepley PetscFunctionReturn(0); 96247923291SMatthew G. Knepley } 963ece3a9fcSMatthew G. Knepley 964ece3a9fcSMatthew G. Knepley PetscErrorCode DMProjectBdFieldLabelLocal_Plex(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Ncc, const PetscInt comps[], Vec localU, 965ece3a9fcSMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 966ece3a9fcSMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 967ece3a9fcSMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 968ece3a9fcSMatthew G. Knepley PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 969ece3a9fcSMatthew G. Knepley InsertMode mode, Vec localX) 970ece3a9fcSMatthew G. Knepley { 971ece3a9fcSMatthew G. Knepley PetscFunctionBegin; 972*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMProjectLocal_Generic_Plex(dm, time, localU, Ncc, comps, label, numIds, ids, DM_BC_ESSENTIAL_BD_FIELD, (void (**)(void)) funcs, NULL, mode, localX)); 973ece3a9fcSMatthew G. Knepley PetscFunctionReturn(0); 974ece3a9fcSMatthew G. Knepley } 975