1130d5748SToby Isaac #include <petsc/private/petscfeimpl.h> /*I "petscfe.h" I*/ 2130d5748SToby Isaac 3130d5748SToby Isaac static PetscErrorCode PetscSpaceSetFromOptions_Ptrimmed(PetscOptionItems *PetscOptionsObject,PetscSpace sp) 4130d5748SToby Isaac { 5130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 6130d5748SToby Isaac 7130d5748SToby Isaac PetscFunctionBegin; 8d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"PetscSpace polynomial options"); 99566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-petscspace_ptrimmed_form_degree", "form degree of trimmed space", "PetscSpacePTrimmedSetFormDegree", pt->formDegree, &(pt->formDegree), NULL)); 10d0609cedSBarry Smith PetscOptionsHeadEnd(); 11130d5748SToby Isaac PetscFunctionReturn(0); 12130d5748SToby Isaac } 13130d5748SToby Isaac 14130d5748SToby Isaac static PetscErrorCode PetscSpacePTrimmedView_Ascii(PetscSpace sp, PetscViewer v) 15130d5748SToby Isaac { 16130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 17ccb4e88aSToby Isaac PetscInt f, tdegree; 18130d5748SToby Isaac 19130d5748SToby Isaac PetscFunctionBegin; 20130d5748SToby Isaac f = pt->formDegree; 21ccb4e88aSToby Isaac tdegree = f == 0 ? sp->degree : sp->degree + 1; 2263a3b9bcSJacob 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))); 23130d5748SToby Isaac PetscFunctionReturn(0); 24130d5748SToby Isaac } 25130d5748SToby Isaac 26130d5748SToby Isaac static PetscErrorCode PetscSpaceView_Ptrimmed(PetscSpace sp, PetscViewer viewer) 27130d5748SToby Isaac { 28130d5748SToby Isaac PetscBool iascii; 29130d5748SToby Isaac 30130d5748SToby Isaac PetscFunctionBegin; 31130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 32130d5748SToby Isaac PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 339566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 349566063dSJacob Faibussowitsch if (iascii) PetscCall(PetscSpacePTrimmedView_Ascii(sp, viewer)); 35130d5748SToby Isaac PetscFunctionReturn(0); 36130d5748SToby Isaac } 37130d5748SToby Isaac 38130d5748SToby Isaac static PetscErrorCode PetscSpaceDestroy_Ptrimmed(PetscSpace sp) 39130d5748SToby Isaac { 40130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 41130d5748SToby Isaac 42130d5748SToby Isaac PetscFunctionBegin; 439566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject) sp, "PetscSpacePTrimmedGetFormDegree_C", NULL)); 449566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject) sp, "PetscSpacePTrimmedSetFormDegree_C", NULL)); 45130d5748SToby Isaac if (pt->subspaces) { 46130d5748SToby Isaac PetscInt d; 47130d5748SToby Isaac 48130d5748SToby Isaac for (d = 0; d < sp->Nv; ++d) { 499566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&pt->subspaces[d])); 50130d5748SToby Isaac } 51130d5748SToby Isaac } 529566063dSJacob Faibussowitsch PetscCall(PetscFree(pt->subspaces)); 539566063dSJacob Faibussowitsch PetscCall(PetscFree(pt)); 54130d5748SToby Isaac PetscFunctionReturn(0); 55130d5748SToby Isaac } 56130d5748SToby Isaac 57130d5748SToby Isaac static PetscErrorCode PetscSpaceSetUp_Ptrimmed(PetscSpace sp) 58130d5748SToby Isaac { 59130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 60130d5748SToby Isaac PetscInt Nf; 61130d5748SToby Isaac 62130d5748SToby Isaac PetscFunctionBegin; 63130d5748SToby Isaac if (pt->setupCalled) PetscFunctionReturn(0); 641dca8a05SBarry 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); 659566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt(sp->Nv, PetscAbsInt(pt->formDegree), &Nf)); 66130d5748SToby Isaac if (sp->Nc == PETSC_DETERMINE) { 67130d5748SToby Isaac sp->Nc = Nf; 68130d5748SToby Isaac } 6963a3b9bcSJacob 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); 70130d5748SToby Isaac if (sp->Nc != Nf) { 71130d5748SToby Isaac PetscSpace subsp; 72130d5748SToby Isaac PetscInt nCopies = sp->Nc / Nf; 73130d5748SToby Isaac PetscInt Nv, deg, maxDeg; 74130d5748SToby Isaac PetscInt formDegree = pt->formDegree; 75130d5748SToby Isaac const char *prefix; 76130d5748SToby Isaac const char *name; 77130d5748SToby Isaac char subname[PETSC_MAX_PATH_LEN]; 78130d5748SToby Isaac 799566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(sp, PETSCSPACESUM)); 809566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetConcatenate(sp, PETSC_TRUE)); 819566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetNumSubspaces(sp, nCopies)); 829566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(PetscObjectComm((PetscObject)sp), &subsp)); 839566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)sp, &prefix)); 849566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)subsp, prefix)); 859566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)subsp, "sumcomp_")); 86130d5748SToby Isaac if (((PetscObject)sp)->name) { 879566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sp, &name)); 889566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(subname, PETSC_MAX_PATH_LEN-1, "%s sum component", name)); 899566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)subsp, subname)); 90130d5748SToby Isaac } else { 919566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)subsp, "sum component")); 92130d5748SToby Isaac } 939566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(subsp, PETSCSPACEPTRIMMED)); 949566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sp, &Nv)); 959566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(subsp, Nv)); 969566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(subsp, Nf)); 979566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(sp, °, &maxDeg)); 989566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetDegree(subsp, deg, maxDeg)); 999566063dSJacob Faibussowitsch PetscCall(PetscSpacePTrimmedSetFormDegree(subsp, formDegree)); 1009566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(subsp)); 101130d5748SToby Isaac for (PetscInt i = 0; i < nCopies; i++) { 1029566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetSubspace(sp, i, subsp)); 103130d5748SToby Isaac } 1049566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&subsp)); 1059566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sp)); 106130d5748SToby Isaac PetscFunctionReturn(0); 107130d5748SToby Isaac } 108130d5748SToby Isaac if (sp->degree == PETSC_DEFAULT) { 109130d5748SToby Isaac sp->degree = 0; 110130d5748SToby Isaac } else if (sp->degree < 0) { 11163a3b9bcSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_OUTOFRANGE, "Invalid negative degree %" PetscInt_FMT, sp->degree); 112130d5748SToby Isaac } 113ccb4e88aSToby Isaac sp->maxDegree = (pt->formDegree == 0 || PetscAbsInt(pt->formDegree) == sp->Nv) ? sp->degree : sp->degree + 1; 114130d5748SToby Isaac if (pt->formDegree == 0 || PetscAbsInt(pt->formDegree) == sp->Nv) { 115130d5748SToby Isaac // Convert to regular polynomial space 1169566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(sp, PETSCSPACEPOLYNOMIAL)); 1179566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sp)); 118130d5748SToby Isaac PetscFunctionReturn(0); 119130d5748SToby Isaac } 120130d5748SToby Isaac pt->setupCalled = PETSC_TRUE; 121130d5748SToby Isaac PetscFunctionReturn(0); 122130d5748SToby Isaac } 123130d5748SToby Isaac 124130d5748SToby Isaac static PetscErrorCode PetscSpaceGetDimension_Ptrimmed(PetscSpace sp, PetscInt *dim) 125130d5748SToby Isaac { 126130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 127130d5748SToby Isaac PetscInt f; 128130d5748SToby Isaac PetscInt Nf; 129130d5748SToby Isaac 130130d5748SToby Isaac PetscFunctionBegin; 131130d5748SToby Isaac f = pt->formDegree; 132130d5748SToby Isaac // For PetscSpace, degree refers to the largest complete polynomial degree contained in the space which 133130d5748SToby Isaac // is equal to the index of a P trimmed space only for 0-forms: otherwise, the index is degree + 1 1349566063dSJacob Faibussowitsch PetscCall(PetscDTPTrimmedSize(sp->Nv, f == 0 ? sp->degree : sp->degree + 1, pt->formDegree, dim)); 1359566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt(sp->Nv, PetscAbsInt(pt->formDegree), &Nf)); 136130d5748SToby Isaac *dim *= (sp->Nc / Nf); 137130d5748SToby Isaac PetscFunctionReturn(0); 138130d5748SToby Isaac } 139130d5748SToby Isaac 140130d5748SToby Isaac /* 141130d5748SToby Isaac p in [0, npoints), i in [0, pdim), c in [0, Nc) 142130d5748SToby Isaac 143130d5748SToby Isaac B[p][i][c] = B[p][i_scalar][c][c] 144130d5748SToby Isaac */ 145130d5748SToby Isaac static PetscErrorCode PetscSpaceEvaluate_Ptrimmed(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[]) 146130d5748SToby Isaac { 147130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 148130d5748SToby Isaac DM dm = sp->dm; 149130d5748SToby Isaac PetscInt jet, degree, Nf, Ncopies, Njet; 150130d5748SToby Isaac PetscInt Nc = sp->Nc; 151130d5748SToby Isaac PetscInt f; 152130d5748SToby Isaac PetscInt dim = sp->Nv; 153130d5748SToby Isaac PetscReal *eval; 154130d5748SToby Isaac PetscInt Nb; 155130d5748SToby Isaac 156130d5748SToby Isaac PetscFunctionBegin; 157130d5748SToby Isaac if (!pt->setupCalled) { 1589566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sp)); 1599566063dSJacob Faibussowitsch PetscCall(PetscSpaceEvaluate(sp, npoints, points, B, D, H)); 160130d5748SToby Isaac PetscFunctionReturn(0); 161130d5748SToby Isaac } 162130d5748SToby Isaac if (H) { 163130d5748SToby Isaac jet = 2; 164130d5748SToby Isaac } else if (D) { 165130d5748SToby Isaac jet = 1; 166130d5748SToby Isaac } else { 167130d5748SToby Isaac jet = 0; 168130d5748SToby Isaac } 169130d5748SToby Isaac f = pt->formDegree; 170130d5748SToby Isaac degree = f == 0 ? sp->degree : sp->degree + 1; 1719566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt(dim, PetscAbsInt(f), &Nf)); 172130d5748SToby Isaac Ncopies = Nc / Nf; 17308401ef6SPierre Jolivet PetscCheck(Ncopies == 1,PetscObjectComm((PetscObject) sp), PETSC_ERR_PLIB, "Multicopy spaces should have been converted to PETSCSPACESUM"); 1749566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt(dim + jet, dim, &Njet)); 1759566063dSJacob Faibussowitsch PetscCall(PetscDTPTrimmedSize(dim, degree, f, &Nb)); 1769566063dSJacob Faibussowitsch PetscCall(DMGetWorkArray(dm, Nb * Nf * Njet * npoints, MPIU_REAL, &eval)); 1779566063dSJacob Faibussowitsch PetscCall(PetscDTPTrimmedEvalJet(dim, npoints, points, degree, f, jet, eval)); 178130d5748SToby Isaac if (B) { 179130d5748SToby Isaac PetscInt p_strl = Nf*Nb; 180130d5748SToby Isaac PetscInt b_strl = Nf; 181130d5748SToby Isaac PetscInt v_strl = 1; 182130d5748SToby Isaac 183130d5748SToby Isaac PetscInt b_strr = Nf*Njet*npoints; 184130d5748SToby Isaac PetscInt v_strr = Njet*npoints; 185130d5748SToby Isaac PetscInt p_strr = 1; 186130d5748SToby Isaac 187130d5748SToby Isaac for (PetscInt v = 0; v < Nf; v++) { 188130d5748SToby Isaac for (PetscInt b = 0; b < Nb; b++) { 189130d5748SToby Isaac for (PetscInt p = 0; p < npoints; p++) { 190130d5748SToby Isaac B[p*p_strl + b*b_strl + v*v_strl] = eval[b*b_strr + v*v_strr + p*p_strr]; 191130d5748SToby Isaac } 192130d5748SToby Isaac } 193130d5748SToby Isaac } 194130d5748SToby Isaac } 195130d5748SToby Isaac if (D) { 196ccb4e88aSToby Isaac PetscInt p_strl = dim*Nf*Nb; 197ccb4e88aSToby Isaac PetscInt b_strl = dim*Nf; 198130d5748SToby Isaac PetscInt v_strl = dim; 199130d5748SToby Isaac PetscInt d_strl = 1; 200130d5748SToby Isaac 201130d5748SToby Isaac PetscInt b_strr = Nf*Njet*npoints; 202130d5748SToby Isaac PetscInt v_strr = Njet*npoints; 203130d5748SToby Isaac PetscInt d_strr = npoints; 204130d5748SToby Isaac PetscInt p_strr = 1; 205130d5748SToby Isaac 206130d5748SToby Isaac for (PetscInt v = 0; v < Nf; v++) { 207130d5748SToby Isaac for (PetscInt d = 0; d < dim; d++) { 208130d5748SToby Isaac for (PetscInt b = 0; b < Nb; b++) { 209130d5748SToby Isaac for (PetscInt p = 0; p < npoints; p++) { 210ccb4e88aSToby Isaac 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]; 211130d5748SToby Isaac } 212130d5748SToby Isaac } 213130d5748SToby Isaac } 214130d5748SToby Isaac } 215130d5748SToby Isaac } 216130d5748SToby Isaac if (H) { 217ccb4e88aSToby Isaac PetscInt p_strl = dim*dim*Nf*Nb; 218ccb4e88aSToby Isaac PetscInt b_strl = dim*dim*Nf; 219ccb4e88aSToby Isaac PetscInt v_strl = dim*dim; 220130d5748SToby Isaac PetscInt d1_strl = dim; 221130d5748SToby Isaac PetscInt d2_strl = 1; 222130d5748SToby Isaac 223130d5748SToby Isaac PetscInt b_strr = Nf*Njet*npoints; 224130d5748SToby Isaac PetscInt v_strr = Njet*npoints; 225130d5748SToby Isaac PetscInt j_strr = npoints; 226130d5748SToby Isaac PetscInt p_strr = 1; 227130d5748SToby Isaac 228130d5748SToby Isaac PetscInt *derivs; 2299566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(dim, &derivs)); 230130d5748SToby Isaac for (PetscInt d1 = 0; d1 < dim; d1++) { 231130d5748SToby Isaac for (PetscInt d2 = 0; d2 < dim; d2++) { 232130d5748SToby Isaac PetscInt j; 233130d5748SToby Isaac derivs[d1]++; 234130d5748SToby Isaac derivs[d2]++; 2359566063dSJacob Faibussowitsch PetscCall(PetscDTGradedOrderToIndex(dim, derivs, &j)); 236130d5748SToby Isaac derivs[d1]--; 237130d5748SToby Isaac derivs[d2]--; 238130d5748SToby Isaac for (PetscInt v = 0; v < Nf; v++) { 239130d5748SToby Isaac for (PetscInt b = 0; b < Nb; b++) { 240130d5748SToby Isaac for (PetscInt p = 0; p < npoints; p++) { 241ccb4e88aSToby Isaac 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]; 242130d5748SToby Isaac } 243130d5748SToby Isaac } 244130d5748SToby Isaac } 245130d5748SToby Isaac } 246130d5748SToby Isaac } 2479566063dSJacob Faibussowitsch PetscCall(PetscFree(derivs)); 248130d5748SToby Isaac } 2499566063dSJacob Faibussowitsch PetscCall(DMRestoreWorkArray(dm, Nb * Nf * Njet * npoints, MPIU_REAL, &eval)); 250130d5748SToby Isaac PetscFunctionReturn(0); 251130d5748SToby Isaac } 252130d5748SToby Isaac 253130d5748SToby Isaac /*@ 254130d5748SToby Isaac PetscSpacePTrimmedSetFormDegree - Set the form degree of the trimmed polynomials. 255130d5748SToby Isaac 256130d5748SToby Isaac Input Parameters: 257130d5748SToby Isaac + sp - the function space object 258130d5748SToby Isaac - formDegree - the form degree 259130d5748SToby Isaac 260130d5748SToby Isaac Options Database: 261130d5748SToby Isaac . -petscspace_ptrimmed_form_degree <int> - The trimmed polynomial form degree 262130d5748SToby Isaac 263130d5748SToby Isaac Level: intermediate 264130d5748SToby Isaac 265*db781477SPatrick Sanan .seealso: `PetscDTAltV`, `PetscDTPTrimmedEvalJet()`, `PetscSpacePTrimmedGetFormDegree()` 266130d5748SToby Isaac @*/ 267130d5748SToby Isaac PetscErrorCode PetscSpacePTrimmedSetFormDegree(PetscSpace sp, PetscInt formDegree) 268130d5748SToby Isaac { 269130d5748SToby Isaac PetscFunctionBegin; 270130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 271cac4c232SBarry Smith PetscTryMethod(sp,"PetscSpacePTrimmedSetFormDegree_C",(PetscSpace,PetscInt),(sp,formDegree)); 272130d5748SToby Isaac PetscFunctionReturn(0); 273130d5748SToby Isaac } 274130d5748SToby Isaac 275130d5748SToby Isaac /*@ 276130d5748SToby Isaac PetscSpacePTrimmedGetFormDegree - Get the form degree of the trimmed polynomials. 277130d5748SToby Isaac 278130d5748SToby Isaac Input Parameters: 279130d5748SToby Isaac . sp - the function space object 280130d5748SToby Isaac 281130d5748SToby Isaac Output Parameters: 282130d5748SToby Isaac . formDegee - the form degree 283130d5748SToby Isaac 284130d5748SToby Isaac Level: intermediate 285130d5748SToby Isaac 286*db781477SPatrick Sanan .seealso: `PetscDTAltV`, `PetscDTPTrimmedEvalJet()`, `PetscSpacePTrimmedSetFormDegree()` 287130d5748SToby Isaac @*/ 288130d5748SToby Isaac PetscErrorCode PetscSpacePTrimmedGetFormDegree(PetscSpace sp, PetscInt *formDegree) 289130d5748SToby Isaac { 290130d5748SToby Isaac PetscFunctionBegin; 291130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 292dadcf809SJacob Faibussowitsch PetscValidIntPointer(formDegree, 2); 293cac4c232SBarry Smith PetscTryMethod(sp,"PetscSpacePTrimmedGetFormDegree_C",(PetscSpace,PetscInt*),(sp,formDegree)); 294130d5748SToby Isaac PetscFunctionReturn(0); 295130d5748SToby Isaac } 296130d5748SToby Isaac 297130d5748SToby Isaac static PetscErrorCode PetscSpacePTrimmedSetFormDegree_Ptrimmed(PetscSpace sp, PetscInt formDegree) 298130d5748SToby Isaac { 299130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 300130d5748SToby Isaac 301130d5748SToby Isaac PetscFunctionBegin; 302130d5748SToby Isaac pt->formDegree = formDegree; 303130d5748SToby Isaac PetscFunctionReturn(0); 304130d5748SToby Isaac } 305130d5748SToby Isaac 306130d5748SToby Isaac static PetscErrorCode PetscSpacePTrimmedGetFormDegree_Ptrimmed(PetscSpace sp, PetscInt *formDegree) 307130d5748SToby Isaac { 308130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 309130d5748SToby Isaac 310130d5748SToby Isaac PetscFunctionBegin; 311130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 312dadcf809SJacob Faibussowitsch PetscValidIntPointer(formDegree, 2); 313130d5748SToby Isaac *formDegree = pt->formDegree; 314130d5748SToby Isaac PetscFunctionReturn(0); 315130d5748SToby Isaac } 316130d5748SToby Isaac 317130d5748SToby Isaac static PetscErrorCode PetscSpaceGetHeightSubspace_Ptrimmed(PetscSpace sp, PetscInt height, PetscSpace *subsp) 318130d5748SToby Isaac { 319130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 320130d5748SToby Isaac PetscInt dim; 321130d5748SToby Isaac 322130d5748SToby Isaac PetscFunctionBegin; 3239566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sp, &dim)); 3241dca8a05SBarry 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); 3259566063dSJacob Faibussowitsch if (!pt->subspaces) PetscCall(PetscCalloc1(dim, &(pt->subspaces))); 326130d5748SToby Isaac if ((dim - height) <= PetscAbsInt(pt->formDegree)) { 327130d5748SToby Isaac if (!pt->subspaces[height-1]) { 328130d5748SToby Isaac PetscInt Nc, degree, Nf, Ncopies, Nfsub; 329130d5748SToby Isaac PetscSpace sub; 330130d5748SToby Isaac const char *name; 331130d5748SToby Isaac 3329566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(sp, &Nc)); 3339566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt(dim, PetscAbsInt(pt->formDegree), &Nf)); 3349566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt((dim-height), PetscAbsInt(pt->formDegree), &Nfsub)); 335130d5748SToby Isaac Ncopies = Nf / Nc; 3369566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(sp, °ree, NULL)); 337130d5748SToby Isaac 3389566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(PetscObjectComm((PetscObject) sp), &sub)); 3399566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) sp, &name)); 3409566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject) sub, name)); 3419566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(sub, PETSCSPACEPTRIMMED)); 3429566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(sub, Nfsub * Ncopies)); 3439566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetDegree(sub, degree, PETSC_DETERMINE)); 3449566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(sub, dim-height)); 3459566063dSJacob Faibussowitsch PetscCall(PetscSpacePTrimmedSetFormDegree(sub, pt->formDegree)); 3469566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sub)); 347130d5748SToby Isaac pt->subspaces[height-1] = sub; 348130d5748SToby Isaac } 349130d5748SToby Isaac *subsp = pt->subspaces[height-1]; 350130d5748SToby Isaac } else { 351130d5748SToby Isaac *subsp = NULL; 352130d5748SToby Isaac } 353130d5748SToby Isaac PetscFunctionReturn(0); 354130d5748SToby Isaac } 355130d5748SToby Isaac 356130d5748SToby Isaac static PetscErrorCode PetscSpaceInitialize_Ptrimmed(PetscSpace sp) 357130d5748SToby Isaac { 358130d5748SToby Isaac PetscFunctionBegin; 3599566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject) sp, "PetscSpacePTrimmedGetFormDegree_C", PetscSpacePTrimmedGetFormDegree_Ptrimmed)); 3609566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject) sp, "PetscSpacePTrimmedSetFormDegree_C", PetscSpacePTrimmedSetFormDegree_Ptrimmed)); 361130d5748SToby Isaac sp->ops->setfromoptions = PetscSpaceSetFromOptions_Ptrimmed; 362130d5748SToby Isaac sp->ops->setup = PetscSpaceSetUp_Ptrimmed; 363130d5748SToby Isaac sp->ops->view = PetscSpaceView_Ptrimmed; 364130d5748SToby Isaac sp->ops->destroy = PetscSpaceDestroy_Ptrimmed; 365130d5748SToby Isaac sp->ops->getdimension = PetscSpaceGetDimension_Ptrimmed; 366130d5748SToby Isaac sp->ops->evaluate = PetscSpaceEvaluate_Ptrimmed; 367130d5748SToby Isaac sp->ops->getheightsubspace = PetscSpaceGetHeightSubspace_Ptrimmed; 368130d5748SToby Isaac PetscFunctionReturn(0); 369130d5748SToby Isaac } 370130d5748SToby Isaac 371130d5748SToby Isaac /*MC 372130d5748SToby Isaac PETSCSPACEPTRIMMED = "ptrimmed" - A PetscSpace object that encapsulates a trimmed polynomial space. 373130d5748SToby Isaac 374130d5748SToby Isaac Level: intermediate 375130d5748SToby Isaac 376*db781477SPatrick Sanan .seealso: `PetscSpaceType`, `PetscSpaceCreate()`, `PetscSpaceSetType()`, `PetscDTPTrimmedEvalJet()` 377130d5748SToby Isaac M*/ 378130d5748SToby Isaac 379130d5748SToby Isaac PETSC_EXTERN PetscErrorCode PetscSpaceCreate_Ptrimmed(PetscSpace sp) 380130d5748SToby Isaac { 381130d5748SToby Isaac PetscSpace_Ptrimmed *pt; 382130d5748SToby Isaac 383130d5748SToby Isaac PetscFunctionBegin; 384130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 3859566063dSJacob Faibussowitsch PetscCall(PetscNewLog(sp,&pt)); 386130d5748SToby Isaac sp->data = pt; 387130d5748SToby Isaac 388130d5748SToby Isaac pt->subspaces = NULL; 389130d5748SToby Isaac sp->Nc = PETSC_DETERMINE; 390130d5748SToby Isaac 3919566063dSJacob Faibussowitsch PetscCall(PetscSpaceInitialize_Ptrimmed(sp)); 392130d5748SToby Isaac PetscFunctionReturn(0); 393130d5748SToby Isaac } 394