1130d5748SToby Isaac #include <petsc/private/petscfeimpl.h> /*I "petscfe.h" I*/ 2130d5748SToby Isaac 3d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSetFromOptions_Ptrimmed(PetscSpace sp, PetscOptionItems *PetscOptionsObject) 4d71ae5a4SJacob Faibussowitsch { 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(); 113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12130d5748SToby Isaac } 13130d5748SToby Isaac 14d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpacePTrimmedView_Ascii(PetscSpace sp, PetscViewer v) 15d71ae5a4SJacob Faibussowitsch { 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))); 233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24130d5748SToby Isaac } 25130d5748SToby Isaac 26d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceView_Ptrimmed(PetscSpace sp, PetscViewer viewer) 27d71ae5a4SJacob Faibussowitsch { 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)); 353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 36130d5748SToby Isaac } 37130d5748SToby Isaac 38d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceDestroy_Ptrimmed(PetscSpace sp) 39d71ae5a4SJacob Faibussowitsch { 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 4848a46eb9SPierre Jolivet for (d = 0; d < sp->Nv; ++d) PetscCall(PetscSpaceDestroy(&pt->subspaces[d])); 49130d5748SToby Isaac } 509566063dSJacob Faibussowitsch PetscCall(PetscFree(pt->subspaces)); 519566063dSJacob Faibussowitsch PetscCall(PetscFree(pt)); 523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 53130d5748SToby Isaac } 54130d5748SToby Isaac 55d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSetUp_Ptrimmed(PetscSpace sp) 56d71ae5a4SJacob Faibussowitsch { 57130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *)sp->data; 58130d5748SToby Isaac PetscInt Nf; 59130d5748SToby Isaac 60130d5748SToby Isaac PetscFunctionBegin; 613ba16761SJacob Faibussowitsch if (pt->setupCalled) PetscFunctionReturn(PETSC_SUCCESS); 621dca8a05SBarry 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); 639566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt(sp->Nv, PetscAbsInt(pt->formDegree), &Nf)); 64ad540459SPierre Jolivet if (sp->Nc == PETSC_DETERMINE) sp->Nc = Nf; 6563a3b9bcSJacob 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); 66130d5748SToby Isaac if (sp->Nc != Nf) { 67130d5748SToby Isaac PetscSpace subsp; 68130d5748SToby Isaac PetscInt nCopies = sp->Nc / Nf; 69130d5748SToby Isaac PetscInt Nv, deg, maxDeg; 70130d5748SToby Isaac PetscInt formDegree = pt->formDegree; 71130d5748SToby Isaac const char *prefix; 72130d5748SToby Isaac const char *name; 73130d5748SToby Isaac char subname[PETSC_MAX_PATH_LEN]; 74130d5748SToby Isaac 759566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(sp, PETSCSPACESUM)); 769566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetConcatenate(sp, PETSC_TRUE)); 779566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetNumSubspaces(sp, nCopies)); 789566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(PetscObjectComm((PetscObject)sp), &subsp)); 799566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)sp, &prefix)); 809566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)subsp, prefix)); 819566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)subsp, "sumcomp_")); 82130d5748SToby Isaac if (((PetscObject)sp)->name) { 839566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sp, &name)); 849566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(subname, PETSC_MAX_PATH_LEN - 1, "%s sum component", name)); 859566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)subsp, subname)); 861baa6e33SBarry Smith } else PetscCall(PetscObjectSetName((PetscObject)subsp, "sum component")); 879566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(subsp, PETSCSPACEPTRIMMED)); 889566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sp, &Nv)); 899566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(subsp, Nv)); 909566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(subsp, Nf)); 919566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(sp, °, &maxDeg)); 929566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetDegree(subsp, deg, maxDeg)); 939566063dSJacob Faibussowitsch PetscCall(PetscSpacePTrimmedSetFormDegree(subsp, formDegree)); 949566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(subsp)); 9548a46eb9SPierre Jolivet for (PetscInt i = 0; i < nCopies; i++) PetscCall(PetscSpaceSumSetSubspace(sp, i, subsp)); 969566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&subsp)); 979566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sp)); 983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 99130d5748SToby Isaac } 100130d5748SToby Isaac if (sp->degree == PETSC_DEFAULT) { 101130d5748SToby Isaac sp->degree = 0; 102130d5748SToby Isaac } else if (sp->degree < 0) { 10363a3b9bcSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_OUTOFRANGE, "Invalid negative degree %" PetscInt_FMT, sp->degree); 104130d5748SToby Isaac } 105ccb4e88aSToby Isaac sp->maxDegree = (pt->formDegree == 0 || PetscAbsInt(pt->formDegree) == sp->Nv) ? sp->degree : sp->degree + 1; 106130d5748SToby Isaac if (pt->formDegree == 0 || PetscAbsInt(pt->formDegree) == sp->Nv) { 107130d5748SToby Isaac // Convert to regular polynomial space 1089566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(sp, PETSCSPACEPOLYNOMIAL)); 1099566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sp)); 1103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 111130d5748SToby Isaac } 112130d5748SToby Isaac pt->setupCalled = PETSC_TRUE; 1133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 114130d5748SToby Isaac } 115130d5748SToby Isaac 116d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceGetDimension_Ptrimmed(PetscSpace sp, PetscInt *dim) 117d71ae5a4SJacob Faibussowitsch { 118130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *)sp->data; 119130d5748SToby Isaac PetscInt f; 120130d5748SToby Isaac PetscInt Nf; 121130d5748SToby Isaac 122130d5748SToby Isaac PetscFunctionBegin; 123130d5748SToby Isaac f = pt->formDegree; 124130d5748SToby Isaac // For PetscSpace, degree refers to the largest complete polynomial degree contained in the space which 125130d5748SToby Isaac // is equal to the index of a P trimmed space only for 0-forms: otherwise, the index is degree + 1 1269566063dSJacob Faibussowitsch PetscCall(PetscDTPTrimmedSize(sp->Nv, f == 0 ? sp->degree : sp->degree + 1, pt->formDegree, dim)); 1279566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt(sp->Nv, PetscAbsInt(pt->formDegree), &Nf)); 128130d5748SToby Isaac *dim *= (sp->Nc / Nf); 1293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 130130d5748SToby Isaac } 131130d5748SToby Isaac 132130d5748SToby Isaac /* 133130d5748SToby Isaac p in [0, npoints), i in [0, pdim), c in [0, Nc) 134130d5748SToby Isaac 135130d5748SToby Isaac B[p][i][c] = B[p][i_scalar][c][c] 136130d5748SToby Isaac */ 137d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceEvaluate_Ptrimmed(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[]) 138d71ae5a4SJacob Faibussowitsch { 139130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *)sp->data; 140130d5748SToby Isaac DM dm = sp->dm; 141130d5748SToby Isaac PetscInt jet, degree, Nf, Ncopies, Njet; 142130d5748SToby Isaac PetscInt Nc = sp->Nc; 143130d5748SToby Isaac PetscInt f; 144130d5748SToby Isaac PetscInt dim = sp->Nv; 145130d5748SToby Isaac PetscReal *eval; 146130d5748SToby Isaac PetscInt Nb; 147130d5748SToby Isaac 148130d5748SToby Isaac PetscFunctionBegin; 149130d5748SToby Isaac if (!pt->setupCalled) { 1509566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sp)); 1519566063dSJacob Faibussowitsch PetscCall(PetscSpaceEvaluate(sp, npoints, points, B, D, H)); 1523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 153130d5748SToby Isaac } 154130d5748SToby Isaac if (H) { 155130d5748SToby Isaac jet = 2; 156130d5748SToby Isaac } else if (D) { 157130d5748SToby Isaac jet = 1; 158130d5748SToby Isaac } else { 159130d5748SToby Isaac jet = 0; 160130d5748SToby Isaac } 161130d5748SToby Isaac f = pt->formDegree; 162130d5748SToby Isaac degree = f == 0 ? sp->degree : sp->degree + 1; 1639566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt(dim, PetscAbsInt(f), &Nf)); 164130d5748SToby Isaac Ncopies = Nc / Nf; 16508401ef6SPierre Jolivet PetscCheck(Ncopies == 1, PetscObjectComm((PetscObject)sp), PETSC_ERR_PLIB, "Multicopy spaces should have been converted to PETSCSPACESUM"); 1669566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt(dim + jet, dim, &Njet)); 1679566063dSJacob Faibussowitsch PetscCall(PetscDTPTrimmedSize(dim, degree, f, &Nb)); 1689566063dSJacob Faibussowitsch PetscCall(DMGetWorkArray(dm, Nb * Nf * Njet * npoints, MPIU_REAL, &eval)); 1699566063dSJacob Faibussowitsch PetscCall(PetscDTPTrimmedEvalJet(dim, npoints, points, degree, f, jet, eval)); 170130d5748SToby Isaac if (B) { 171130d5748SToby Isaac PetscInt p_strl = Nf * Nb; 172130d5748SToby Isaac PetscInt b_strl = Nf; 173130d5748SToby Isaac PetscInt v_strl = 1; 174130d5748SToby Isaac 175130d5748SToby Isaac PetscInt b_strr = Nf * Njet * npoints; 176130d5748SToby Isaac PetscInt v_strr = Njet * npoints; 177130d5748SToby Isaac PetscInt p_strr = 1; 178130d5748SToby Isaac 179130d5748SToby Isaac for (PetscInt v = 0; v < Nf; v++) { 180130d5748SToby Isaac for (PetscInt b = 0; b < Nb; b++) { 181ad540459SPierre Jolivet 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]; 182130d5748SToby Isaac } 183130d5748SToby Isaac } 184130d5748SToby Isaac } 185130d5748SToby Isaac if (D) { 186ccb4e88aSToby Isaac PetscInt p_strl = dim * Nf * Nb; 187ccb4e88aSToby Isaac PetscInt b_strl = dim * Nf; 188130d5748SToby Isaac PetscInt v_strl = dim; 189130d5748SToby Isaac PetscInt d_strl = 1; 190130d5748SToby Isaac 191130d5748SToby Isaac PetscInt b_strr = Nf * Njet * npoints; 192130d5748SToby Isaac PetscInt v_strr = Njet * npoints; 193130d5748SToby Isaac PetscInt d_strr = npoints; 194130d5748SToby Isaac PetscInt p_strr = 1; 195130d5748SToby Isaac 196130d5748SToby Isaac for (PetscInt v = 0; v < Nf; v++) { 197130d5748SToby Isaac for (PetscInt d = 0; d < dim; d++) { 198130d5748SToby Isaac for (PetscInt b = 0; b < Nb; b++) { 199ad540459SPierre Jolivet 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]; 200130d5748SToby Isaac } 201130d5748SToby Isaac } 202130d5748SToby Isaac } 203130d5748SToby Isaac } 204130d5748SToby Isaac if (H) { 205ccb4e88aSToby Isaac PetscInt p_strl = dim * dim * Nf * Nb; 206ccb4e88aSToby Isaac PetscInt b_strl = dim * dim * Nf; 207ccb4e88aSToby Isaac PetscInt v_strl = dim * dim; 208130d5748SToby Isaac PetscInt d1_strl = dim; 209130d5748SToby Isaac PetscInt d2_strl = 1; 210130d5748SToby Isaac 211130d5748SToby Isaac PetscInt b_strr = Nf * Njet * npoints; 212130d5748SToby Isaac PetscInt v_strr = Njet * npoints; 213130d5748SToby Isaac PetscInt j_strr = npoints; 214130d5748SToby Isaac PetscInt p_strr = 1; 215130d5748SToby Isaac 216130d5748SToby Isaac PetscInt *derivs; 2179566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(dim, &derivs)); 218130d5748SToby Isaac for (PetscInt d1 = 0; d1 < dim; d1++) { 219130d5748SToby Isaac for (PetscInt d2 = 0; d2 < dim; d2++) { 220130d5748SToby Isaac PetscInt j; 221130d5748SToby Isaac derivs[d1]++; 222130d5748SToby Isaac derivs[d2]++; 2239566063dSJacob Faibussowitsch PetscCall(PetscDTGradedOrderToIndex(dim, derivs, &j)); 224130d5748SToby Isaac derivs[d1]--; 225130d5748SToby Isaac derivs[d2]--; 226130d5748SToby Isaac for (PetscInt v = 0; v < Nf; v++) { 227130d5748SToby Isaac for (PetscInt b = 0; b < Nb; b++) { 228ad540459SPierre Jolivet 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]; 229130d5748SToby Isaac } 230130d5748SToby Isaac } 231130d5748SToby Isaac } 232130d5748SToby Isaac } 2339566063dSJacob Faibussowitsch PetscCall(PetscFree(derivs)); 234130d5748SToby Isaac } 2359566063dSJacob Faibussowitsch PetscCall(DMRestoreWorkArray(dm, Nb * Nf * Njet * npoints, MPIU_REAL, &eval)); 2363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 237130d5748SToby Isaac } 238130d5748SToby Isaac 239130d5748SToby Isaac /*@ 240130d5748SToby Isaac PetscSpacePTrimmedSetFormDegree - Set the form degree of the trimmed polynomials. 241130d5748SToby Isaac 242130d5748SToby Isaac Input Parameters: 243130d5748SToby Isaac + sp - the function space object 244130d5748SToby Isaac - formDegree - the form degree 245130d5748SToby Isaac 246dce8aebaSBarry Smith Options Database Key: 247130d5748SToby Isaac . -petscspace_ptrimmed_form_degree <int> - The trimmed polynomial form degree 248130d5748SToby Isaac 249130d5748SToby Isaac Level: intermediate 250130d5748SToby Isaac 251dce8aebaSBarry Smith .seealso: `PetscSpace`, `PetscDTAltV`, `PetscDTPTrimmedEvalJet()`, `PetscSpacePTrimmedGetFormDegree()` 252130d5748SToby Isaac @*/ 253d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSpacePTrimmedSetFormDegree(PetscSpace sp, PetscInt formDegree) 254d71ae5a4SJacob Faibussowitsch { 255130d5748SToby Isaac PetscFunctionBegin; 256130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 257cac4c232SBarry Smith PetscTryMethod(sp, "PetscSpacePTrimmedSetFormDegree_C", (PetscSpace, PetscInt), (sp, formDegree)); 2583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 259130d5748SToby Isaac } 260130d5748SToby Isaac 261130d5748SToby Isaac /*@ 262130d5748SToby Isaac PetscSpacePTrimmedGetFormDegree - Get the form degree of the trimmed polynomials. 263130d5748SToby Isaac 2642fe279fdSBarry Smith Input Parameter: 265130d5748SToby Isaac . sp - the function space object 266130d5748SToby Isaac 2672fe279fdSBarry Smith Output Parameter: 268130d5748SToby Isaac . formDegee - the form degree 269130d5748SToby Isaac 270130d5748SToby Isaac Level: intermediate 271130d5748SToby Isaac 272dce8aebaSBarry Smith .seealso: `PetscSpace`, `PetscDTAltV`, `PetscDTPTrimmedEvalJet()`, `PetscSpacePTrimmedSetFormDegree()` 273130d5748SToby Isaac @*/ 274d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSpacePTrimmedGetFormDegree(PetscSpace sp, PetscInt *formDegree) 275d71ae5a4SJacob Faibussowitsch { 276130d5748SToby Isaac PetscFunctionBegin; 277130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 278dadcf809SJacob Faibussowitsch PetscValidIntPointer(formDegree, 2); 279cac4c232SBarry Smith PetscTryMethod(sp, "PetscSpacePTrimmedGetFormDegree_C", (PetscSpace, PetscInt *), (sp, formDegree)); 2803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 281130d5748SToby Isaac } 282130d5748SToby Isaac 283d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpacePTrimmedSetFormDegree_Ptrimmed(PetscSpace sp, PetscInt formDegree) 284d71ae5a4SJacob Faibussowitsch { 285130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *)sp->data; 286130d5748SToby Isaac 287130d5748SToby Isaac PetscFunctionBegin; 288130d5748SToby Isaac pt->formDegree = formDegree; 2893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 290130d5748SToby Isaac } 291130d5748SToby Isaac 292d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpacePTrimmedGetFormDegree_Ptrimmed(PetscSpace sp, PetscInt *formDegree) 293d71ae5a4SJacob Faibussowitsch { 294130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *)sp->data; 295130d5748SToby Isaac 296130d5748SToby Isaac PetscFunctionBegin; 297130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 298dadcf809SJacob Faibussowitsch PetscValidIntPointer(formDegree, 2); 299130d5748SToby Isaac *formDegree = pt->formDegree; 3003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 301130d5748SToby Isaac } 302130d5748SToby Isaac 303d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceGetHeightSubspace_Ptrimmed(PetscSpace sp, PetscInt height, PetscSpace *subsp) 304d71ae5a4SJacob Faibussowitsch { 305130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *)sp->data; 306130d5748SToby Isaac PetscInt dim; 307130d5748SToby Isaac 308130d5748SToby Isaac PetscFunctionBegin; 3099566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sp, &dim)); 3101dca8a05SBarry 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); 3119566063dSJacob Faibussowitsch if (!pt->subspaces) PetscCall(PetscCalloc1(dim, &(pt->subspaces))); 312130d5748SToby Isaac if ((dim - height) <= PetscAbsInt(pt->formDegree)) { 313130d5748SToby Isaac if (!pt->subspaces[height - 1]) { 314130d5748SToby Isaac PetscInt Nc, degree, Nf, Ncopies, Nfsub; 315130d5748SToby Isaac PetscSpace sub; 316130d5748SToby Isaac const char *name; 317130d5748SToby Isaac 3189566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(sp, &Nc)); 3199566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt(dim, PetscAbsInt(pt->formDegree), &Nf)); 3209566063dSJacob Faibussowitsch PetscCall(PetscDTBinomialInt((dim - height), PetscAbsInt(pt->formDegree), &Nfsub)); 321130d5748SToby Isaac Ncopies = Nf / Nc; 3229566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(sp, °ree, NULL)); 323130d5748SToby Isaac 3249566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(PetscObjectComm((PetscObject)sp), &sub)); 3259566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sp, &name)); 3269566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)sub, name)); 3279566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(sub, PETSCSPACEPTRIMMED)); 3289566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(sub, Nfsub * Ncopies)); 3299566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetDegree(sub, degree, PETSC_DETERMINE)); 3309566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(sub, dim - height)); 3319566063dSJacob Faibussowitsch PetscCall(PetscSpacePTrimmedSetFormDegree(sub, pt->formDegree)); 3329566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sub)); 333130d5748SToby Isaac pt->subspaces[height - 1] = sub; 334130d5748SToby Isaac } 335130d5748SToby Isaac *subsp = pt->subspaces[height - 1]; 336130d5748SToby Isaac } else { 337130d5748SToby Isaac *subsp = NULL; 338130d5748SToby Isaac } 3393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 340130d5748SToby Isaac } 341130d5748SToby Isaac 342d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceInitialize_Ptrimmed(PetscSpace sp) 343d71ae5a4SJacob Faibussowitsch { 344130d5748SToby Isaac PetscFunctionBegin; 3459566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpacePTrimmedGetFormDegree_C", PetscSpacePTrimmedGetFormDegree_Ptrimmed)); 3469566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpacePTrimmedSetFormDegree_C", PetscSpacePTrimmedSetFormDegree_Ptrimmed)); 347130d5748SToby Isaac sp->ops->setfromoptions = PetscSpaceSetFromOptions_Ptrimmed; 348130d5748SToby Isaac sp->ops->setup = PetscSpaceSetUp_Ptrimmed; 349130d5748SToby Isaac sp->ops->view = PetscSpaceView_Ptrimmed; 350130d5748SToby Isaac sp->ops->destroy = PetscSpaceDestroy_Ptrimmed; 351130d5748SToby Isaac sp->ops->getdimension = PetscSpaceGetDimension_Ptrimmed; 352130d5748SToby Isaac sp->ops->evaluate = PetscSpaceEvaluate_Ptrimmed; 353130d5748SToby Isaac sp->ops->getheightsubspace = PetscSpaceGetHeightSubspace_Ptrimmed; 3543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 355130d5748SToby Isaac } 356130d5748SToby Isaac 357130d5748SToby Isaac /*MC 358dce8aebaSBarry Smith PETSCSPACEPTRIMMED = "ptrimmed" - A `PetscSpace` object that encapsulates a trimmed polynomial space. 359130d5748SToby Isaac 360130d5748SToby Isaac Level: intermediate 361130d5748SToby Isaac 362*b24fb147SBarry Smith Developer Note: 363*b24fb147SBarry Smith Need a good easy to understand reference for trimmed poynomial spaces 364*b24fb147SBarry Smith 365dce8aebaSBarry Smith .seealso: `PetscSpace`, `PetscSpaceType`, `PetscSpaceCreate()`, `PetscSpaceSetType()`, `PetscDTPTrimmedEvalJet()` 366130d5748SToby Isaac M*/ 367130d5748SToby Isaac 368d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscSpaceCreate_Ptrimmed(PetscSpace sp) 369d71ae5a4SJacob Faibussowitsch { 370130d5748SToby Isaac PetscSpace_Ptrimmed *pt; 371130d5748SToby Isaac 372130d5748SToby Isaac PetscFunctionBegin; 373130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 3744dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&pt)); 375130d5748SToby Isaac sp->data = pt; 376130d5748SToby Isaac 377130d5748SToby Isaac pt->subspaces = NULL; 378130d5748SToby Isaac sp->Nc = PETSC_DETERMINE; 379130d5748SToby Isaac 3809566063dSJacob Faibussowitsch PetscCall(PetscSpaceInitialize_Ptrimmed(sp)); 3813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 382130d5748SToby Isaac } 383