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)); 90*1baa6e33SBarry Smith } else PetscCall(PetscObjectSetName((PetscObject)subsp, "sum component")); 919566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(subsp, PETSCSPACEPTRIMMED)); 929566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sp, &Nv)); 939566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(subsp, Nv)); 949566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(subsp, Nf)); 959566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(sp, °, &maxDeg)); 969566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetDegree(subsp, deg, maxDeg)); 979566063dSJacob Faibussowitsch PetscCall(PetscSpacePTrimmedSetFormDegree(subsp, formDegree)); 989566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(subsp)); 99130d5748SToby Isaac for (PetscInt i = 0; i < nCopies; i++) { 1009566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetSubspace(sp, i, subsp)); 101130d5748SToby Isaac } 1029566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&subsp)); 1039566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sp)); 104130d5748SToby Isaac PetscFunctionReturn(0); 105130d5748SToby Isaac } 106130d5748SToby Isaac if (sp->degree == PETSC_DEFAULT) { 107130d5748SToby Isaac sp->degree = 0; 108130d5748SToby Isaac } else if (sp->degree < 0) { 10963a3b9bcSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_OUTOFRANGE, "Invalid negative degree %" PetscInt_FMT, sp->degree); 110130d5748SToby Isaac } 111ccb4e88aSToby Isaac sp->maxDegree = (pt->formDegree == 0 || PetscAbsInt(pt->formDegree) == sp->Nv) ? sp->degree : sp->degree + 1; 112130d5748SToby Isaac if (pt->formDegree == 0 || PetscAbsInt(pt->formDegree) == sp->Nv) { 113130d5748SToby Isaac // Convert to regular polynomial space 1149566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(sp, PETSCSPACEPOLYNOMIAL)); 1159566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sp)); 116130d5748SToby Isaac PetscFunctionReturn(0); 117130d5748SToby Isaac } 118130d5748SToby Isaac pt->setupCalled = PETSC_TRUE; 119130d5748SToby Isaac PetscFunctionReturn(0); 120130d5748SToby Isaac } 121130d5748SToby Isaac 122130d5748SToby Isaac static PetscErrorCode PetscSpaceGetDimension_Ptrimmed(PetscSpace sp, PetscInt *dim) 123130d5748SToby Isaac { 124130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 125130d5748SToby Isaac PetscInt f; 126130d5748SToby Isaac PetscInt Nf; 127130d5748SToby Isaac 128130d5748SToby Isaac PetscFunctionBegin; 129130d5748SToby Isaac f = pt->formDegree; 130130d5748SToby Isaac // For PetscSpace, degree refers to the largest complete polynomial degree contained in the space which 131130d5748SToby Isaac // is equal to the index of a P trimmed space only for 0-forms: otherwise, the index is degree + 1 1329566063dSJacob Faibussowitsch PetscCall(PetscDTPTrimmedSize(sp->Nv, f == 0 ? sp->degree : sp->degree + 1, pt->formDegree, dim)); 1339566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt(sp->Nv, PetscAbsInt(pt->formDegree), &Nf)); 134130d5748SToby Isaac *dim *= (sp->Nc / Nf); 135130d5748SToby Isaac PetscFunctionReturn(0); 136130d5748SToby Isaac } 137130d5748SToby Isaac 138130d5748SToby Isaac /* 139130d5748SToby Isaac p in [0, npoints), i in [0, pdim), c in [0, Nc) 140130d5748SToby Isaac 141130d5748SToby Isaac B[p][i][c] = B[p][i_scalar][c][c] 142130d5748SToby Isaac */ 143130d5748SToby Isaac static PetscErrorCode PetscSpaceEvaluate_Ptrimmed(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[]) 144130d5748SToby Isaac { 145130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 146130d5748SToby Isaac DM dm = sp->dm; 147130d5748SToby Isaac PetscInt jet, degree, Nf, Ncopies, Njet; 148130d5748SToby Isaac PetscInt Nc = sp->Nc; 149130d5748SToby Isaac PetscInt f; 150130d5748SToby Isaac PetscInt dim = sp->Nv; 151130d5748SToby Isaac PetscReal *eval; 152130d5748SToby Isaac PetscInt Nb; 153130d5748SToby Isaac 154130d5748SToby Isaac PetscFunctionBegin; 155130d5748SToby Isaac if (!pt->setupCalled) { 1569566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sp)); 1579566063dSJacob Faibussowitsch PetscCall(PetscSpaceEvaluate(sp, npoints, points, B, D, H)); 158130d5748SToby Isaac PetscFunctionReturn(0); 159130d5748SToby Isaac } 160130d5748SToby Isaac if (H) { 161130d5748SToby Isaac jet = 2; 162130d5748SToby Isaac } else if (D) { 163130d5748SToby Isaac jet = 1; 164130d5748SToby Isaac } else { 165130d5748SToby Isaac jet = 0; 166130d5748SToby Isaac } 167130d5748SToby Isaac f = pt->formDegree; 168130d5748SToby Isaac degree = f == 0 ? sp->degree : sp->degree + 1; 1699566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt(dim, PetscAbsInt(f), &Nf)); 170130d5748SToby Isaac Ncopies = Nc / Nf; 17108401ef6SPierre Jolivet PetscCheck(Ncopies == 1,PetscObjectComm((PetscObject) sp), PETSC_ERR_PLIB, "Multicopy spaces should have been converted to PETSCSPACESUM"); 1729566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt(dim + jet, dim, &Njet)); 1739566063dSJacob Faibussowitsch PetscCall(PetscDTPTrimmedSize(dim, degree, f, &Nb)); 1749566063dSJacob Faibussowitsch PetscCall(DMGetWorkArray(dm, Nb * Nf * Njet * npoints, MPIU_REAL, &eval)); 1759566063dSJacob Faibussowitsch PetscCall(PetscDTPTrimmedEvalJet(dim, npoints, points, degree, f, jet, eval)); 176130d5748SToby Isaac if (B) { 177130d5748SToby Isaac PetscInt p_strl = Nf*Nb; 178130d5748SToby Isaac PetscInt b_strl = Nf; 179130d5748SToby Isaac PetscInt v_strl = 1; 180130d5748SToby Isaac 181130d5748SToby Isaac PetscInt b_strr = Nf*Njet*npoints; 182130d5748SToby Isaac PetscInt v_strr = Njet*npoints; 183130d5748SToby Isaac PetscInt p_strr = 1; 184130d5748SToby Isaac 185130d5748SToby Isaac for (PetscInt v = 0; v < Nf; v++) { 186130d5748SToby Isaac for (PetscInt b = 0; b < Nb; b++) { 187130d5748SToby Isaac for (PetscInt p = 0; p < npoints; p++) { 188130d5748SToby Isaac B[p*p_strl + b*b_strl + v*v_strl] = eval[b*b_strr + v*v_strr + p*p_strr]; 189130d5748SToby Isaac } 190130d5748SToby Isaac } 191130d5748SToby Isaac } 192130d5748SToby Isaac } 193130d5748SToby Isaac if (D) { 194ccb4e88aSToby Isaac PetscInt p_strl = dim*Nf*Nb; 195ccb4e88aSToby Isaac PetscInt b_strl = dim*Nf; 196130d5748SToby Isaac PetscInt v_strl = dim; 197130d5748SToby Isaac PetscInt d_strl = 1; 198130d5748SToby Isaac 199130d5748SToby Isaac PetscInt b_strr = Nf*Njet*npoints; 200130d5748SToby Isaac PetscInt v_strr = Njet*npoints; 201130d5748SToby Isaac PetscInt d_strr = npoints; 202130d5748SToby Isaac PetscInt p_strr = 1; 203130d5748SToby Isaac 204130d5748SToby Isaac for (PetscInt v = 0; v < Nf; v++) { 205130d5748SToby Isaac for (PetscInt d = 0; d < dim; d++) { 206130d5748SToby Isaac for (PetscInt b = 0; b < Nb; b++) { 207130d5748SToby Isaac for (PetscInt p = 0; p < npoints; p++) { 208ccb4e88aSToby 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]; 209130d5748SToby Isaac } 210130d5748SToby Isaac } 211130d5748SToby Isaac } 212130d5748SToby Isaac } 213130d5748SToby Isaac } 214130d5748SToby Isaac if (H) { 215ccb4e88aSToby Isaac PetscInt p_strl = dim*dim*Nf*Nb; 216ccb4e88aSToby Isaac PetscInt b_strl = dim*dim*Nf; 217ccb4e88aSToby Isaac PetscInt v_strl = dim*dim; 218130d5748SToby Isaac PetscInt d1_strl = dim; 219130d5748SToby Isaac PetscInt d2_strl = 1; 220130d5748SToby Isaac 221130d5748SToby Isaac PetscInt b_strr = Nf*Njet*npoints; 222130d5748SToby Isaac PetscInt v_strr = Njet*npoints; 223130d5748SToby Isaac PetscInt j_strr = npoints; 224130d5748SToby Isaac PetscInt p_strr = 1; 225130d5748SToby Isaac 226130d5748SToby Isaac PetscInt *derivs; 2279566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(dim, &derivs)); 228130d5748SToby Isaac for (PetscInt d1 = 0; d1 < dim; d1++) { 229130d5748SToby Isaac for (PetscInt d2 = 0; d2 < dim; d2++) { 230130d5748SToby Isaac PetscInt j; 231130d5748SToby Isaac derivs[d1]++; 232130d5748SToby Isaac derivs[d2]++; 2339566063dSJacob Faibussowitsch PetscCall(PetscDTGradedOrderToIndex(dim, derivs, &j)); 234130d5748SToby Isaac derivs[d1]--; 235130d5748SToby Isaac derivs[d2]--; 236130d5748SToby Isaac for (PetscInt v = 0; v < Nf; v++) { 237130d5748SToby Isaac for (PetscInt b = 0; b < Nb; b++) { 238130d5748SToby Isaac for (PetscInt p = 0; p < npoints; p++) { 239ccb4e88aSToby 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]; 240130d5748SToby Isaac } 241130d5748SToby Isaac } 242130d5748SToby Isaac } 243130d5748SToby Isaac } 244130d5748SToby Isaac } 2459566063dSJacob Faibussowitsch PetscCall(PetscFree(derivs)); 246130d5748SToby Isaac } 2479566063dSJacob Faibussowitsch PetscCall(DMRestoreWorkArray(dm, Nb * Nf * Njet * npoints, MPIU_REAL, &eval)); 248130d5748SToby Isaac PetscFunctionReturn(0); 249130d5748SToby Isaac } 250130d5748SToby Isaac 251130d5748SToby Isaac /*@ 252130d5748SToby Isaac PetscSpacePTrimmedSetFormDegree - Set the form degree of the trimmed polynomials. 253130d5748SToby Isaac 254130d5748SToby Isaac Input Parameters: 255130d5748SToby Isaac + sp - the function space object 256130d5748SToby Isaac - formDegree - the form degree 257130d5748SToby Isaac 258130d5748SToby Isaac Options Database: 259130d5748SToby Isaac . -petscspace_ptrimmed_form_degree <int> - The trimmed polynomial form degree 260130d5748SToby Isaac 261130d5748SToby Isaac Level: intermediate 262130d5748SToby Isaac 263db781477SPatrick Sanan .seealso: `PetscDTAltV`, `PetscDTPTrimmedEvalJet()`, `PetscSpacePTrimmedGetFormDegree()` 264130d5748SToby Isaac @*/ 265130d5748SToby Isaac PetscErrorCode PetscSpacePTrimmedSetFormDegree(PetscSpace sp, PetscInt formDegree) 266130d5748SToby Isaac { 267130d5748SToby Isaac PetscFunctionBegin; 268130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 269cac4c232SBarry Smith PetscTryMethod(sp,"PetscSpacePTrimmedSetFormDegree_C",(PetscSpace,PetscInt),(sp,formDegree)); 270130d5748SToby Isaac PetscFunctionReturn(0); 271130d5748SToby Isaac } 272130d5748SToby Isaac 273130d5748SToby Isaac /*@ 274130d5748SToby Isaac PetscSpacePTrimmedGetFormDegree - Get the form degree of the trimmed polynomials. 275130d5748SToby Isaac 276130d5748SToby Isaac Input Parameters: 277130d5748SToby Isaac . sp - the function space object 278130d5748SToby Isaac 279130d5748SToby Isaac Output Parameters: 280130d5748SToby Isaac . formDegee - the form degree 281130d5748SToby Isaac 282130d5748SToby Isaac Level: intermediate 283130d5748SToby Isaac 284db781477SPatrick Sanan .seealso: `PetscDTAltV`, `PetscDTPTrimmedEvalJet()`, `PetscSpacePTrimmedSetFormDegree()` 285130d5748SToby Isaac @*/ 286130d5748SToby Isaac PetscErrorCode PetscSpacePTrimmedGetFormDegree(PetscSpace sp, PetscInt *formDegree) 287130d5748SToby Isaac { 288130d5748SToby Isaac PetscFunctionBegin; 289130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 290dadcf809SJacob Faibussowitsch PetscValidIntPointer(formDegree, 2); 291cac4c232SBarry Smith PetscTryMethod(sp,"PetscSpacePTrimmedGetFormDegree_C",(PetscSpace,PetscInt*),(sp,formDegree)); 292130d5748SToby Isaac PetscFunctionReturn(0); 293130d5748SToby Isaac } 294130d5748SToby Isaac 295130d5748SToby Isaac static PetscErrorCode PetscSpacePTrimmedSetFormDegree_Ptrimmed(PetscSpace sp, PetscInt formDegree) 296130d5748SToby Isaac { 297130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 298130d5748SToby Isaac 299130d5748SToby Isaac PetscFunctionBegin; 300130d5748SToby Isaac pt->formDegree = formDegree; 301130d5748SToby Isaac PetscFunctionReturn(0); 302130d5748SToby Isaac } 303130d5748SToby Isaac 304130d5748SToby Isaac static PetscErrorCode PetscSpacePTrimmedGetFormDegree_Ptrimmed(PetscSpace sp, PetscInt *formDegree) 305130d5748SToby Isaac { 306130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 307130d5748SToby Isaac 308130d5748SToby Isaac PetscFunctionBegin; 309130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 310dadcf809SJacob Faibussowitsch PetscValidIntPointer(formDegree, 2); 311130d5748SToby Isaac *formDegree = pt->formDegree; 312130d5748SToby Isaac PetscFunctionReturn(0); 313130d5748SToby Isaac } 314130d5748SToby Isaac 315130d5748SToby Isaac static PetscErrorCode PetscSpaceGetHeightSubspace_Ptrimmed(PetscSpace sp, PetscInt height, PetscSpace *subsp) 316130d5748SToby Isaac { 317130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 318130d5748SToby Isaac PetscInt dim; 319130d5748SToby Isaac 320130d5748SToby Isaac PetscFunctionBegin; 3219566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sp, &dim)); 3221dca8a05SBarry 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); 3239566063dSJacob Faibussowitsch if (!pt->subspaces) PetscCall(PetscCalloc1(dim, &(pt->subspaces))); 324130d5748SToby Isaac if ((dim - height) <= PetscAbsInt(pt->formDegree)) { 325130d5748SToby Isaac if (!pt->subspaces[height-1]) { 326130d5748SToby Isaac PetscInt Nc, degree, Nf, Ncopies, Nfsub; 327130d5748SToby Isaac PetscSpace sub; 328130d5748SToby Isaac const char *name; 329130d5748SToby Isaac 3309566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(sp, &Nc)); 3319566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt(dim, PetscAbsInt(pt->formDegree), &Nf)); 3329566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt((dim-height), PetscAbsInt(pt->formDegree), &Nfsub)); 333130d5748SToby Isaac Ncopies = Nf / Nc; 3349566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(sp, °ree, NULL)); 335130d5748SToby Isaac 3369566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(PetscObjectComm((PetscObject) sp), &sub)); 3379566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) sp, &name)); 3389566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject) sub, name)); 3399566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(sub, PETSCSPACEPTRIMMED)); 3409566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(sub, Nfsub * Ncopies)); 3419566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetDegree(sub, degree, PETSC_DETERMINE)); 3429566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(sub, dim-height)); 3439566063dSJacob Faibussowitsch PetscCall(PetscSpacePTrimmedSetFormDegree(sub, pt->formDegree)); 3449566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sub)); 345130d5748SToby Isaac pt->subspaces[height-1] = sub; 346130d5748SToby Isaac } 347130d5748SToby Isaac *subsp = pt->subspaces[height-1]; 348130d5748SToby Isaac } else { 349130d5748SToby Isaac *subsp = NULL; 350130d5748SToby Isaac } 351130d5748SToby Isaac PetscFunctionReturn(0); 352130d5748SToby Isaac } 353130d5748SToby Isaac 354130d5748SToby Isaac static PetscErrorCode PetscSpaceInitialize_Ptrimmed(PetscSpace sp) 355130d5748SToby Isaac { 356130d5748SToby Isaac PetscFunctionBegin; 3579566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject) sp, "PetscSpacePTrimmedGetFormDegree_C", PetscSpacePTrimmedGetFormDegree_Ptrimmed)); 3589566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject) sp, "PetscSpacePTrimmedSetFormDegree_C", PetscSpacePTrimmedSetFormDegree_Ptrimmed)); 359130d5748SToby Isaac sp->ops->setfromoptions = PetscSpaceSetFromOptions_Ptrimmed; 360130d5748SToby Isaac sp->ops->setup = PetscSpaceSetUp_Ptrimmed; 361130d5748SToby Isaac sp->ops->view = PetscSpaceView_Ptrimmed; 362130d5748SToby Isaac sp->ops->destroy = PetscSpaceDestroy_Ptrimmed; 363130d5748SToby Isaac sp->ops->getdimension = PetscSpaceGetDimension_Ptrimmed; 364130d5748SToby Isaac sp->ops->evaluate = PetscSpaceEvaluate_Ptrimmed; 365130d5748SToby Isaac sp->ops->getheightsubspace = PetscSpaceGetHeightSubspace_Ptrimmed; 366130d5748SToby Isaac PetscFunctionReturn(0); 367130d5748SToby Isaac } 368130d5748SToby Isaac 369130d5748SToby Isaac /*MC 370130d5748SToby Isaac PETSCSPACEPTRIMMED = "ptrimmed" - A PetscSpace object that encapsulates a trimmed polynomial space. 371130d5748SToby Isaac 372130d5748SToby Isaac Level: intermediate 373130d5748SToby Isaac 374db781477SPatrick Sanan .seealso: `PetscSpaceType`, `PetscSpaceCreate()`, `PetscSpaceSetType()`, `PetscDTPTrimmedEvalJet()` 375130d5748SToby Isaac M*/ 376130d5748SToby Isaac 377130d5748SToby Isaac PETSC_EXTERN PetscErrorCode PetscSpaceCreate_Ptrimmed(PetscSpace sp) 378130d5748SToby Isaac { 379130d5748SToby Isaac PetscSpace_Ptrimmed *pt; 380130d5748SToby Isaac 381130d5748SToby Isaac PetscFunctionBegin; 382130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 3839566063dSJacob Faibussowitsch PetscCall(PetscNewLog(sp,&pt)); 384130d5748SToby Isaac sp->data = pt; 385130d5748SToby Isaac 386130d5748SToby Isaac pt->subspaces = NULL; 387130d5748SToby Isaac sp->Nc = PETSC_DETERMINE; 388130d5748SToby Isaac 3899566063dSJacob Faibussowitsch PetscCall(PetscSpaceInitialize_Ptrimmed(sp)); 390130d5748SToby Isaac PetscFunctionReturn(0); 391130d5748SToby Isaac } 392