1130d5748SToby Isaac #include <petsc/private/petscfeimpl.h> /*I "petscfe.h" I*/ 2130d5748SToby Isaac 39371c9d4SSatish Balay static PetscErrorCode PetscSpaceSetFromOptions_Ptrimmed(PetscSpace sp, PetscOptionItems *PetscOptionsObject) { 4130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *)sp->data; 5130d5748SToby Isaac 6130d5748SToby Isaac PetscFunctionBegin; 7d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "PetscSpace polynomial options"); 89566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-petscspace_ptrimmed_form_degree", "form degree of trimmed space", "PetscSpacePTrimmedSetFormDegree", pt->formDegree, &(pt->formDegree), NULL)); 9d0609cedSBarry Smith PetscOptionsHeadEnd(); 10130d5748SToby Isaac PetscFunctionReturn(0); 11130d5748SToby Isaac } 12130d5748SToby Isaac 139371c9d4SSatish Balay static PetscErrorCode PetscSpacePTrimmedView_Ascii(PetscSpace sp, PetscViewer v) { 14130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *)sp->data; 15ccb4e88aSToby Isaac PetscInt f, tdegree; 16130d5748SToby Isaac 17130d5748SToby Isaac PetscFunctionBegin; 18130d5748SToby Isaac f = pt->formDegree; 19ccb4e88aSToby Isaac tdegree = f == 0 ? sp->degree : sp->degree + 1; 2063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(v, "Trimmed polynomials %" PetscInt_FMT "%s-forms of degree %" PetscInt_FMT " (P-%" PetscInt_FMT "/\\%" PetscInt_FMT ")\n", PetscAbsInt(f), f < 0 ? "*" : "", sp->degree, tdegree, PetscAbsInt(f))); 21130d5748SToby Isaac PetscFunctionReturn(0); 22130d5748SToby Isaac } 23130d5748SToby Isaac 249371c9d4SSatish Balay static PetscErrorCode PetscSpaceView_Ptrimmed(PetscSpace sp, PetscViewer viewer) { 25130d5748SToby Isaac PetscBool iascii; 26130d5748SToby Isaac 27130d5748SToby Isaac PetscFunctionBegin; 28130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 29130d5748SToby Isaac PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 309566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 319566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscSpacePTrimmedView_Ascii(sp, viewer)); 32130d5748SToby Isaac PetscFunctionReturn(0); 33130d5748SToby Isaac } 34130d5748SToby Isaac 359371c9d4SSatish Balay static PetscErrorCode PetscSpaceDestroy_Ptrimmed(PetscSpace sp) { 36130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *)sp->data; 37130d5748SToby Isaac 38130d5748SToby Isaac PetscFunctionBegin; 399566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpacePTrimmedGetFormDegree_C", NULL)); 409566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpacePTrimmedSetFormDegree_C", NULL)); 41130d5748SToby Isaac if (pt->subspaces) { 42130d5748SToby Isaac PetscInt d; 43130d5748SToby Isaac 44*48a46eb9SPierre Jolivet for (d = 0; d < sp->Nv; ++d) PetscCall(PetscSpaceDestroy(&pt->subspaces[d])); 45130d5748SToby Isaac } 469566063dSJacob Faibussowitsch PetscCall(PetscFree(pt->subspaces)); 479566063dSJacob Faibussowitsch PetscCall(PetscFree(pt)); 48130d5748SToby Isaac PetscFunctionReturn(0); 49130d5748SToby Isaac } 50130d5748SToby Isaac 519371c9d4SSatish Balay static PetscErrorCode PetscSpaceSetUp_Ptrimmed(PetscSpace sp) { 52130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *)sp->data; 53130d5748SToby Isaac PetscInt Nf; 54130d5748SToby Isaac 55130d5748SToby Isaac PetscFunctionBegin; 56130d5748SToby Isaac if (pt->setupCalled) PetscFunctionReturn(0); 571dca8a05SBarry Smith PetscCheck(pt->formDegree >= -sp->Nv && pt->formDegree <= sp->Nv, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_OUTOFRANGE, "Form degree %" PetscInt_FMT " not in valid range [%" PetscInt_FMT ",%" PetscInt_FMT "]", pt->formDegree, sp->Nv, sp->Nv); 589566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt(sp->Nv, PetscAbsInt(pt->formDegree), &Nf)); 599371c9d4SSatish Balay if (sp->Nc == PETSC_DETERMINE) { sp->Nc = Nf; } 6063a3b9bcSJacob Faibussowitsch PetscCheck(sp->Nc % Nf == 0, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_INCOMP, "Number of components %" PetscInt_FMT " is not a multiple of form dimension %" PetscInt_FMT, sp->Nc, Nf); 61130d5748SToby Isaac if (sp->Nc != Nf) { 62130d5748SToby Isaac PetscSpace subsp; 63130d5748SToby Isaac PetscInt nCopies = sp->Nc / Nf; 64130d5748SToby Isaac PetscInt Nv, deg, maxDeg; 65130d5748SToby Isaac PetscInt formDegree = pt->formDegree; 66130d5748SToby Isaac const char *prefix; 67130d5748SToby Isaac const char *name; 68130d5748SToby Isaac char subname[PETSC_MAX_PATH_LEN]; 69130d5748SToby Isaac 709566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(sp, PETSCSPACESUM)); 719566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetConcatenate(sp, PETSC_TRUE)); 729566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetNumSubspaces(sp, nCopies)); 739566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(PetscObjectComm((PetscObject)sp), &subsp)); 749566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)sp, &prefix)); 759566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)subsp, prefix)); 769566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)subsp, "sumcomp_")); 77130d5748SToby Isaac if (((PetscObject)sp)->name) { 789566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sp, &name)); 799566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(subname, PETSC_MAX_PATH_LEN - 1, "%s sum component", name)); 809566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)subsp, subname)); 811baa6e33SBarry Smith } else PetscCall(PetscObjectSetName((PetscObject)subsp, "sum component")); 829566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(subsp, PETSCSPACEPTRIMMED)); 839566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sp, &Nv)); 849566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(subsp, Nv)); 859566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(subsp, Nf)); 869566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(sp, °, &maxDeg)); 879566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetDegree(subsp, deg, maxDeg)); 889566063dSJacob Faibussowitsch PetscCall(PetscSpacePTrimmedSetFormDegree(subsp, formDegree)); 899566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(subsp)); 90*48a46eb9SPierre Jolivet for (PetscInt i = 0; i < nCopies; i++) PetscCall(PetscSpaceSumSetSubspace(sp, i, subsp)); 919566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&subsp)); 929566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sp)); 93130d5748SToby Isaac PetscFunctionReturn(0); 94130d5748SToby Isaac } 95130d5748SToby Isaac if (sp->degree == PETSC_DEFAULT) { 96130d5748SToby Isaac sp->degree = 0; 97130d5748SToby Isaac } else if (sp->degree < 0) { 9863a3b9bcSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_OUTOFRANGE, "Invalid negative degree %" PetscInt_FMT, sp->degree); 99130d5748SToby Isaac } 100ccb4e88aSToby Isaac sp->maxDegree = (pt->formDegree == 0 || PetscAbsInt(pt->formDegree) == sp->Nv) ? sp->degree : sp->degree + 1; 101130d5748SToby Isaac if (pt->formDegree == 0 || PetscAbsInt(pt->formDegree) == sp->Nv) { 102130d5748SToby Isaac // Convert to regular polynomial space 1039566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(sp, PETSCSPACEPOLYNOMIAL)); 1049566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sp)); 105130d5748SToby Isaac PetscFunctionReturn(0); 106130d5748SToby Isaac } 107130d5748SToby Isaac pt->setupCalled = PETSC_TRUE; 108130d5748SToby Isaac PetscFunctionReturn(0); 109130d5748SToby Isaac } 110130d5748SToby Isaac 1119371c9d4SSatish Balay static PetscErrorCode PetscSpaceGetDimension_Ptrimmed(PetscSpace sp, PetscInt *dim) { 112130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *)sp->data; 113130d5748SToby Isaac PetscInt f; 114130d5748SToby Isaac PetscInt Nf; 115130d5748SToby Isaac 116130d5748SToby Isaac PetscFunctionBegin; 117130d5748SToby Isaac f = pt->formDegree; 118130d5748SToby Isaac // For PetscSpace, degree refers to the largest complete polynomial degree contained in the space which 119130d5748SToby Isaac // is equal to the index of a P trimmed space only for 0-forms: otherwise, the index is degree + 1 1209566063dSJacob Faibussowitsch PetscCall(PetscDTPTrimmedSize(sp->Nv, f == 0 ? sp->degree : sp->degree + 1, pt->formDegree, dim)); 1219566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt(sp->Nv, PetscAbsInt(pt->formDegree), &Nf)); 122130d5748SToby Isaac *dim *= (sp->Nc / Nf); 123130d5748SToby Isaac PetscFunctionReturn(0); 124130d5748SToby Isaac } 125130d5748SToby Isaac 126130d5748SToby Isaac /* 127130d5748SToby Isaac p in [0, npoints), i in [0, pdim), c in [0, Nc) 128130d5748SToby Isaac 129130d5748SToby Isaac B[p][i][c] = B[p][i_scalar][c][c] 130130d5748SToby Isaac */ 1319371c9d4SSatish Balay static PetscErrorCode PetscSpaceEvaluate_Ptrimmed(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[]) { 132130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *)sp->data; 133130d5748SToby Isaac DM dm = sp->dm; 134130d5748SToby Isaac PetscInt jet, degree, Nf, Ncopies, Njet; 135130d5748SToby Isaac PetscInt Nc = sp->Nc; 136130d5748SToby Isaac PetscInt f; 137130d5748SToby Isaac PetscInt dim = sp->Nv; 138130d5748SToby Isaac PetscReal *eval; 139130d5748SToby Isaac PetscInt Nb; 140130d5748SToby Isaac 141130d5748SToby Isaac PetscFunctionBegin; 142130d5748SToby Isaac if (!pt->setupCalled) { 1439566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sp)); 1449566063dSJacob Faibussowitsch PetscCall(PetscSpaceEvaluate(sp, npoints, points, B, D, H)); 145130d5748SToby Isaac PetscFunctionReturn(0); 146130d5748SToby Isaac } 147130d5748SToby Isaac if (H) { 148130d5748SToby Isaac jet = 2; 149130d5748SToby Isaac } else if (D) { 150130d5748SToby Isaac jet = 1; 151130d5748SToby Isaac } else { 152130d5748SToby Isaac jet = 0; 153130d5748SToby Isaac } 154130d5748SToby Isaac f = pt->formDegree; 155130d5748SToby Isaac degree = f == 0 ? sp->degree : sp->degree + 1; 1569566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt(dim, PetscAbsInt(f), &Nf)); 157130d5748SToby Isaac Ncopies = Nc / Nf; 15808401ef6SPierre Jolivet PetscCheck(Ncopies == 1, PetscObjectComm((PetscObject)sp), PETSC_ERR_PLIB, "Multicopy spaces should have been converted to PETSCSPACESUM"); 1599566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt(dim + jet, dim, &Njet)); 1609566063dSJacob Faibussowitsch PetscCall(PetscDTPTrimmedSize(dim, degree, f, &Nb)); 1619566063dSJacob Faibussowitsch PetscCall(DMGetWorkArray(dm, Nb * Nf * Njet * npoints, MPIU_REAL, &eval)); 1629566063dSJacob Faibussowitsch PetscCall(PetscDTPTrimmedEvalJet(dim, npoints, points, degree, f, jet, eval)); 163130d5748SToby Isaac if (B) { 164130d5748SToby Isaac PetscInt p_strl = Nf * Nb; 165130d5748SToby Isaac PetscInt b_strl = Nf; 166130d5748SToby Isaac PetscInt v_strl = 1; 167130d5748SToby Isaac 168130d5748SToby Isaac PetscInt b_strr = Nf * Njet * npoints; 169130d5748SToby Isaac PetscInt v_strr = Njet * npoints; 170130d5748SToby Isaac PetscInt p_strr = 1; 171130d5748SToby Isaac 172130d5748SToby Isaac for (PetscInt v = 0; v < Nf; v++) { 173130d5748SToby Isaac for (PetscInt b = 0; b < Nb; b++) { 1749371c9d4SSatish Balay for (PetscInt p = 0; p < npoints; p++) { B[p * p_strl + b * b_strl + v * v_strl] = eval[b * b_strr + v * v_strr + p * p_strr]; } 175130d5748SToby Isaac } 176130d5748SToby Isaac } 177130d5748SToby Isaac } 178130d5748SToby Isaac if (D) { 179ccb4e88aSToby Isaac PetscInt p_strl = dim * Nf * Nb; 180ccb4e88aSToby Isaac PetscInt b_strl = dim * Nf; 181130d5748SToby Isaac PetscInt v_strl = dim; 182130d5748SToby Isaac PetscInt d_strl = 1; 183130d5748SToby Isaac 184130d5748SToby Isaac PetscInt b_strr = Nf * Njet * npoints; 185130d5748SToby Isaac PetscInt v_strr = Njet * npoints; 186130d5748SToby Isaac PetscInt d_strr = npoints; 187130d5748SToby Isaac PetscInt p_strr = 1; 188130d5748SToby Isaac 189130d5748SToby Isaac for (PetscInt v = 0; v < Nf; v++) { 190130d5748SToby Isaac for (PetscInt d = 0; d < dim; d++) { 191130d5748SToby Isaac for (PetscInt b = 0; b < Nb; b++) { 1929371c9d4SSatish Balay for (PetscInt p = 0; p < npoints; p++) { D[p * p_strl + b * b_strl + v * v_strl + d * d_strl] = eval[b * b_strr + v * v_strr + (1 + d) * d_strr + p * p_strr]; } 193130d5748SToby Isaac } 194130d5748SToby Isaac } 195130d5748SToby Isaac } 196130d5748SToby Isaac } 197130d5748SToby Isaac if (H) { 198ccb4e88aSToby Isaac PetscInt p_strl = dim * dim * Nf * Nb; 199ccb4e88aSToby Isaac PetscInt b_strl = dim * dim * Nf; 200ccb4e88aSToby Isaac PetscInt v_strl = dim * dim; 201130d5748SToby Isaac PetscInt d1_strl = dim; 202130d5748SToby Isaac PetscInt d2_strl = 1; 203130d5748SToby Isaac 204130d5748SToby Isaac PetscInt b_strr = Nf * Njet * npoints; 205130d5748SToby Isaac PetscInt v_strr = Njet * npoints; 206130d5748SToby Isaac PetscInt j_strr = npoints; 207130d5748SToby Isaac PetscInt p_strr = 1; 208130d5748SToby Isaac 209130d5748SToby Isaac PetscInt *derivs; 2109566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(dim, &derivs)); 211130d5748SToby Isaac for (PetscInt d1 = 0; d1 < dim; d1++) { 212130d5748SToby Isaac for (PetscInt d2 = 0; d2 < dim; d2++) { 213130d5748SToby Isaac PetscInt j; 214130d5748SToby Isaac derivs[d1]++; 215130d5748SToby Isaac derivs[d2]++; 2169566063dSJacob Faibussowitsch PetscCall(PetscDTGradedOrderToIndex(dim, derivs, &j)); 217130d5748SToby Isaac derivs[d1]--; 218130d5748SToby Isaac derivs[d2]--; 219130d5748SToby Isaac for (PetscInt v = 0; v < Nf; v++) { 220130d5748SToby Isaac for (PetscInt b = 0; b < Nb; b++) { 2219371c9d4SSatish Balay for (PetscInt p = 0; p < npoints; p++) { H[p * p_strl + b * b_strl + v * v_strl + d1 * d1_strl + d2 * d2_strl] = eval[b * b_strr + v * v_strr + j * j_strr + p * p_strr]; } 222130d5748SToby Isaac } 223130d5748SToby Isaac } 224130d5748SToby Isaac } 225130d5748SToby Isaac } 2269566063dSJacob Faibussowitsch PetscCall(PetscFree(derivs)); 227130d5748SToby Isaac } 2289566063dSJacob Faibussowitsch PetscCall(DMRestoreWorkArray(dm, Nb * Nf * Njet * npoints, MPIU_REAL, &eval)); 229130d5748SToby Isaac PetscFunctionReturn(0); 230130d5748SToby Isaac } 231130d5748SToby Isaac 232130d5748SToby Isaac /*@ 233130d5748SToby Isaac PetscSpacePTrimmedSetFormDegree - Set the form degree of the trimmed polynomials. 234130d5748SToby Isaac 235130d5748SToby Isaac Input Parameters: 236130d5748SToby Isaac + sp - the function space object 237130d5748SToby Isaac - formDegree - the form degree 238130d5748SToby Isaac 239130d5748SToby Isaac Options Database: 240130d5748SToby Isaac . -petscspace_ptrimmed_form_degree <int> - The trimmed polynomial form degree 241130d5748SToby Isaac 242130d5748SToby Isaac Level: intermediate 243130d5748SToby Isaac 244db781477SPatrick Sanan .seealso: `PetscDTAltV`, `PetscDTPTrimmedEvalJet()`, `PetscSpacePTrimmedGetFormDegree()` 245130d5748SToby Isaac @*/ 2469371c9d4SSatish Balay PetscErrorCode PetscSpacePTrimmedSetFormDegree(PetscSpace sp, PetscInt formDegree) { 247130d5748SToby Isaac PetscFunctionBegin; 248130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 249cac4c232SBarry Smith PetscTryMethod(sp, "PetscSpacePTrimmedSetFormDegree_C", (PetscSpace, PetscInt), (sp, formDegree)); 250130d5748SToby Isaac PetscFunctionReturn(0); 251130d5748SToby Isaac } 252130d5748SToby Isaac 253130d5748SToby Isaac /*@ 254130d5748SToby Isaac PetscSpacePTrimmedGetFormDegree - Get the form degree of the trimmed polynomials. 255130d5748SToby Isaac 256130d5748SToby Isaac Input Parameters: 257130d5748SToby Isaac . sp - the function space object 258130d5748SToby Isaac 259130d5748SToby Isaac Output Parameters: 260130d5748SToby Isaac . formDegee - the form degree 261130d5748SToby Isaac 262130d5748SToby Isaac Level: intermediate 263130d5748SToby Isaac 264db781477SPatrick Sanan .seealso: `PetscDTAltV`, `PetscDTPTrimmedEvalJet()`, `PetscSpacePTrimmedSetFormDegree()` 265130d5748SToby Isaac @*/ 2669371c9d4SSatish Balay PetscErrorCode PetscSpacePTrimmedGetFormDegree(PetscSpace sp, PetscInt *formDegree) { 267130d5748SToby Isaac PetscFunctionBegin; 268130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 269dadcf809SJacob Faibussowitsch PetscValidIntPointer(formDegree, 2); 270cac4c232SBarry Smith PetscTryMethod(sp, "PetscSpacePTrimmedGetFormDegree_C", (PetscSpace, PetscInt *), (sp, formDegree)); 271130d5748SToby Isaac PetscFunctionReturn(0); 272130d5748SToby Isaac } 273130d5748SToby Isaac 2749371c9d4SSatish Balay static PetscErrorCode PetscSpacePTrimmedSetFormDegree_Ptrimmed(PetscSpace sp, PetscInt formDegree) { 275130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *)sp->data; 276130d5748SToby Isaac 277130d5748SToby Isaac PetscFunctionBegin; 278130d5748SToby Isaac pt->formDegree = formDegree; 279130d5748SToby Isaac PetscFunctionReturn(0); 280130d5748SToby Isaac } 281130d5748SToby Isaac 2829371c9d4SSatish Balay static PetscErrorCode PetscSpacePTrimmedGetFormDegree_Ptrimmed(PetscSpace sp, PetscInt *formDegree) { 283130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *)sp->data; 284130d5748SToby Isaac 285130d5748SToby Isaac PetscFunctionBegin; 286130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 287dadcf809SJacob Faibussowitsch PetscValidIntPointer(formDegree, 2); 288130d5748SToby Isaac *formDegree = pt->formDegree; 289130d5748SToby Isaac PetscFunctionReturn(0); 290130d5748SToby Isaac } 291130d5748SToby Isaac 2929371c9d4SSatish Balay static PetscErrorCode PetscSpaceGetHeightSubspace_Ptrimmed(PetscSpace sp, PetscInt height, PetscSpace *subsp) { 293130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *)sp->data; 294130d5748SToby Isaac PetscInt dim; 295130d5748SToby Isaac 296130d5748SToby Isaac PetscFunctionBegin; 2979566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sp, &dim)); 2981dca8a05SBarry Smith PetscCheck(height <= dim && height >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Asked for space at height %" PetscInt_FMT " for dimension %" PetscInt_FMT " space", height, dim); 2999566063dSJacob Faibussowitsch if (!pt->subspaces) PetscCall(PetscCalloc1(dim, &(pt->subspaces))); 300130d5748SToby Isaac if ((dim - height) <= PetscAbsInt(pt->formDegree)) { 301130d5748SToby Isaac if (!pt->subspaces[height - 1]) { 302130d5748SToby Isaac PetscInt Nc, degree, Nf, Ncopies, Nfsub; 303130d5748SToby Isaac PetscSpace sub; 304130d5748SToby Isaac const char *name; 305130d5748SToby Isaac 3069566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(sp, &Nc)); 3079566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt(dim, PetscAbsInt(pt->formDegree), &Nf)); 3089566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt((dim - height), PetscAbsInt(pt->formDegree), &Nfsub)); 309130d5748SToby Isaac Ncopies = Nf / Nc; 3109566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(sp, °ree, NULL)); 311130d5748SToby Isaac 3129566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(PetscObjectComm((PetscObject)sp), &sub)); 3139566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sp, &name)); 3149566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)sub, name)); 3159566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(sub, PETSCSPACEPTRIMMED)); 3169566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(sub, Nfsub * Ncopies)); 3179566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetDegree(sub, degree, PETSC_DETERMINE)); 3189566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(sub, dim - height)); 3199566063dSJacob Faibussowitsch PetscCall(PetscSpacePTrimmedSetFormDegree(sub, pt->formDegree)); 3209566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sub)); 321130d5748SToby Isaac pt->subspaces[height - 1] = sub; 322130d5748SToby Isaac } 323130d5748SToby Isaac *subsp = pt->subspaces[height - 1]; 324130d5748SToby Isaac } else { 325130d5748SToby Isaac *subsp = NULL; 326130d5748SToby Isaac } 327130d5748SToby Isaac PetscFunctionReturn(0); 328130d5748SToby Isaac } 329130d5748SToby Isaac 3309371c9d4SSatish Balay static PetscErrorCode PetscSpaceInitialize_Ptrimmed(PetscSpace sp) { 331130d5748SToby Isaac PetscFunctionBegin; 3329566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpacePTrimmedGetFormDegree_C", PetscSpacePTrimmedGetFormDegree_Ptrimmed)); 3339566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpacePTrimmedSetFormDegree_C", PetscSpacePTrimmedSetFormDegree_Ptrimmed)); 334130d5748SToby Isaac sp->ops->setfromoptions = PetscSpaceSetFromOptions_Ptrimmed; 335130d5748SToby Isaac sp->ops->setup = PetscSpaceSetUp_Ptrimmed; 336130d5748SToby Isaac sp->ops->view = PetscSpaceView_Ptrimmed; 337130d5748SToby Isaac sp->ops->destroy = PetscSpaceDestroy_Ptrimmed; 338130d5748SToby Isaac sp->ops->getdimension = PetscSpaceGetDimension_Ptrimmed; 339130d5748SToby Isaac sp->ops->evaluate = PetscSpaceEvaluate_Ptrimmed; 340130d5748SToby Isaac sp->ops->getheightsubspace = PetscSpaceGetHeightSubspace_Ptrimmed; 341130d5748SToby Isaac PetscFunctionReturn(0); 342130d5748SToby Isaac } 343130d5748SToby Isaac 344130d5748SToby Isaac /*MC 345130d5748SToby Isaac PETSCSPACEPTRIMMED = "ptrimmed" - A PetscSpace object that encapsulates a trimmed polynomial space. 346130d5748SToby Isaac 347130d5748SToby Isaac Level: intermediate 348130d5748SToby Isaac 349db781477SPatrick Sanan .seealso: `PetscSpaceType`, `PetscSpaceCreate()`, `PetscSpaceSetType()`, `PetscDTPTrimmedEvalJet()` 350130d5748SToby Isaac M*/ 351130d5748SToby Isaac 3529371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscSpaceCreate_Ptrimmed(PetscSpace sp) { 353130d5748SToby Isaac PetscSpace_Ptrimmed *pt; 354130d5748SToby Isaac 355130d5748SToby Isaac PetscFunctionBegin; 356130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 3579566063dSJacob Faibussowitsch PetscCall(PetscNewLog(sp, &pt)); 358130d5748SToby Isaac sp->data = pt; 359130d5748SToby Isaac 360130d5748SToby Isaac pt->subspaces = NULL; 361130d5748SToby Isaac sp->Nc = PETSC_DETERMINE; 362130d5748SToby Isaac 3639566063dSJacob Faibussowitsch PetscCall(PetscSpaceInitialize_Ptrimmed(sp)); 364130d5748SToby Isaac PetscFunctionReturn(0); 365130d5748SToby Isaac } 366