1*130d5748SToby Isaac #include <petsc/private/petscfeimpl.h> /*I "petscfe.h" I*/ 2*130d5748SToby Isaac 3*130d5748SToby Isaac static PetscErrorCode PetscSpaceSetFromOptions_Ptrimmed(PetscOptionItems *PetscOptionsObject,PetscSpace sp) 4*130d5748SToby Isaac { 5*130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 6*130d5748SToby Isaac PetscErrorCode ierr; 7*130d5748SToby Isaac 8*130d5748SToby Isaac PetscFunctionBegin; 9*130d5748SToby Isaac ierr = PetscOptionsHead(PetscOptionsObject,"PetscSpace polynomial options");CHKERRQ(ierr); 10*130d5748SToby Isaac ierr = PetscOptionsInt("-petscspace_ptrimmed_form_degree", "form degree of trimmed space", "PetscSpacePTrimmedSetFormDegree", pt->formDegree, &(pt->formDegree), NULL);CHKERRQ(ierr); 11*130d5748SToby Isaac ierr = PetscOptionsTail();CHKERRQ(ierr); 12*130d5748SToby Isaac PetscFunctionReturn(0); 13*130d5748SToby Isaac } 14*130d5748SToby Isaac 15*130d5748SToby Isaac static PetscErrorCode PetscSpacePTrimmedView_Ascii(PetscSpace sp, PetscViewer v) 16*130d5748SToby Isaac { 17*130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 18*130d5748SToby Isaac PetscInt f; 19*130d5748SToby Isaac PetscErrorCode ierr; 20*130d5748SToby Isaac 21*130d5748SToby Isaac PetscFunctionBegin; 22*130d5748SToby Isaac f = pt->formDegree; 23*130d5748SToby Isaac ierr = PetscViewerASCIIPrintf(v, "Trimmed polynomials %D%s-forms of degree %D\n", PetscAbsInt(f), f < 0 ? "*" : "", sp->maxDegree);CHKERRQ(ierr); 24*130d5748SToby Isaac PetscFunctionReturn(0); 25*130d5748SToby Isaac } 26*130d5748SToby Isaac 27*130d5748SToby Isaac static PetscErrorCode PetscSpaceView_Ptrimmed(PetscSpace sp, PetscViewer viewer) 28*130d5748SToby Isaac { 29*130d5748SToby Isaac PetscBool iascii; 30*130d5748SToby Isaac PetscErrorCode ierr; 31*130d5748SToby Isaac 32*130d5748SToby Isaac PetscFunctionBegin; 33*130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 34*130d5748SToby Isaac PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 35*130d5748SToby Isaac ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 36*130d5748SToby Isaac if (iascii) {ierr = PetscSpacePTrimmedView_Ascii(sp, viewer);CHKERRQ(ierr);} 37*130d5748SToby Isaac PetscFunctionReturn(0); 38*130d5748SToby Isaac } 39*130d5748SToby Isaac 40*130d5748SToby Isaac static PetscErrorCode PetscSpaceDestroy_Ptrimmed(PetscSpace sp) 41*130d5748SToby Isaac { 42*130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 43*130d5748SToby Isaac PetscErrorCode ierr; 44*130d5748SToby Isaac 45*130d5748SToby Isaac PetscFunctionBegin; 46*130d5748SToby Isaac ierr = PetscObjectComposeFunction((PetscObject) sp, "PetscSpacePTrimmedGetFormDegree_C", NULL);CHKERRQ(ierr); 47*130d5748SToby Isaac ierr = PetscObjectComposeFunction((PetscObject) sp, "PetscSpacePTrimmedSetFormDegree_C", NULL);CHKERRQ(ierr); 48*130d5748SToby Isaac if (pt->subspaces) { 49*130d5748SToby Isaac PetscInt d; 50*130d5748SToby Isaac 51*130d5748SToby Isaac for (d = 0; d < sp->Nv; ++d) { 52*130d5748SToby Isaac ierr = PetscSpaceDestroy(&pt->subspaces[d]);CHKERRQ(ierr); 53*130d5748SToby Isaac } 54*130d5748SToby Isaac } 55*130d5748SToby Isaac ierr = PetscFree(pt->subspaces);CHKERRQ(ierr); 56*130d5748SToby Isaac ierr = PetscFree(pt);CHKERRQ(ierr); 57*130d5748SToby Isaac PetscFunctionReturn(0); 58*130d5748SToby Isaac } 59*130d5748SToby Isaac 60*130d5748SToby Isaac static PetscErrorCode PetscSpaceSetUp_Ptrimmed(PetscSpace sp) 61*130d5748SToby Isaac { 62*130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 63*130d5748SToby Isaac PetscInt Nf; 64*130d5748SToby Isaac PetscErrorCode ierr; 65*130d5748SToby Isaac 66*130d5748SToby Isaac PetscFunctionBegin; 67*130d5748SToby Isaac if (pt->setupCalled) PetscFunctionReturn(0); 68*130d5748SToby Isaac if (pt->formDegree < -sp->Nv || pt->formDegree > sp->Nv) SETERRQ3(PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_OUTOFRANGE, "Form degree %D not in valid range [%D,%D]", pt->formDegree, sp->Nv, sp->Nv); 69*130d5748SToby Isaac ierr = PetscDTBinomialInt(sp->Nv, PetscAbsInt(pt->formDegree), &Nf);CHKERRQ(ierr); 70*130d5748SToby Isaac if (sp->Nc == PETSC_DETERMINE) { 71*130d5748SToby Isaac sp->Nc = Nf; 72*130d5748SToby Isaac } 73*130d5748SToby Isaac if (sp->Nc % Nf) SETERRQ2(PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_INCOMP, "Number of components %D is not a multiple of form dimension %D\n", sp->Nc, Nf); 74*130d5748SToby Isaac if (sp->Nc != Nf) { 75*130d5748SToby Isaac PetscSpace subsp; 76*130d5748SToby Isaac PetscInt nCopies = sp->Nc / Nf; 77*130d5748SToby Isaac PetscInt Nv, deg, maxDeg; 78*130d5748SToby Isaac PetscInt formDegree = pt->formDegree; 79*130d5748SToby Isaac const char *prefix; 80*130d5748SToby Isaac const char *name; 81*130d5748SToby Isaac char subname[PETSC_MAX_PATH_LEN]; 82*130d5748SToby Isaac 83*130d5748SToby Isaac ierr = PetscSpaceSetType(sp, PETSCSPACESUM);CHKERRQ(ierr); 84*130d5748SToby Isaac ierr = PetscSpaceSumSetConcatenate(sp, PETSC_TRUE);CHKERRQ(ierr); 85*130d5748SToby Isaac ierr = PetscSpaceSumSetNumSubspaces(sp, nCopies);CHKERRQ(ierr); 86*130d5748SToby Isaac ierr = PetscSpaceCreate(PetscObjectComm((PetscObject)sp), &subsp);CHKERRQ(ierr); 87*130d5748SToby Isaac ierr = PetscObjectGetOptionsPrefix((PetscObject)sp, &prefix);CHKERRQ(ierr); 88*130d5748SToby Isaac ierr = PetscObjectSetOptionsPrefix((PetscObject)subsp, prefix);CHKERRQ(ierr); 89*130d5748SToby Isaac ierr = PetscObjectAppendOptionsPrefix((PetscObject)subsp, "sumcomp_");CHKERRQ(ierr); 90*130d5748SToby Isaac if (((PetscObject)sp)->name) { 91*130d5748SToby Isaac ierr = PetscObjectGetName((PetscObject)sp, &name);CHKERRQ(ierr); 92*130d5748SToby Isaac ierr = PetscSNPrintf(subname, PETSC_MAX_PATH_LEN-1, "%s sum component", name);CHKERRQ(ierr); 93*130d5748SToby Isaac ierr = PetscObjectSetName((PetscObject)subsp, subname);CHKERRQ(ierr); 94*130d5748SToby Isaac } else { 95*130d5748SToby Isaac ierr = PetscObjectSetName((PetscObject)subsp, "sum component");CHKERRQ(ierr); 96*130d5748SToby Isaac } 97*130d5748SToby Isaac ierr = PetscSpaceSetType(subsp, PETSCSPACEPTRIMMED);CHKERRQ(ierr); 98*130d5748SToby Isaac ierr = PetscSpaceGetNumVariables(sp, &Nv);CHKERRQ(ierr); 99*130d5748SToby Isaac ierr = PetscSpaceSetNumVariables(subsp, Nv);CHKERRQ(ierr); 100*130d5748SToby Isaac ierr = PetscSpaceSetNumComponents(subsp, Nf);CHKERRQ(ierr); 101*130d5748SToby Isaac ierr = PetscSpaceGetDegree(sp, °, &maxDeg);CHKERRQ(ierr); 102*130d5748SToby Isaac ierr = PetscSpaceSetDegree(subsp, deg, maxDeg);CHKERRQ(ierr); 103*130d5748SToby Isaac ierr = PetscSpacePTrimmedSetFormDegree(subsp, formDegree);CHKERRQ(ierr); 104*130d5748SToby Isaac ierr = PetscSpaceSetUp(subsp);CHKERRQ(ierr); 105*130d5748SToby Isaac for (PetscInt i = 0; i < nCopies; i++) { 106*130d5748SToby Isaac ierr = PetscSpaceSumSetSubspace(sp, i, subsp);CHKERRQ(ierr); 107*130d5748SToby Isaac } 108*130d5748SToby Isaac ierr = PetscSpaceDestroy(&subsp);CHKERRQ(ierr); 109*130d5748SToby Isaac ierr = PetscSpaceSetUp(sp);CHKERRQ(ierr); 110*130d5748SToby Isaac PetscFunctionReturn(0); 111*130d5748SToby Isaac } 112*130d5748SToby Isaac if (sp->degree == PETSC_DEFAULT) { 113*130d5748SToby Isaac sp->degree = 0; 114*130d5748SToby Isaac } else if (sp->degree < 0) { 115*130d5748SToby Isaac SETERRQ1(PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_OUTOFRANGE, "Invalid negative degree %D\n", sp->degree); 116*130d5748SToby Isaac } 117*130d5748SToby Isaac if (pt->formDegree == 0 || PetscAbsInt(pt->formDegree) == sp->Nv) { 118*130d5748SToby Isaac // Convert to regular polynomial space 119*130d5748SToby Isaac ierr = PetscSpaceSetType(sp, PETSCSPACEPOLYNOMIAL);CHKERRQ(ierr); 120*130d5748SToby Isaac ierr = PetscSpaceSetUp(sp);CHKERRQ(ierr); 121*130d5748SToby Isaac PetscFunctionReturn(0); 122*130d5748SToby Isaac } 123*130d5748SToby Isaac pt->setupCalled = PETSC_TRUE; 124*130d5748SToby Isaac PetscFunctionReturn(0); 125*130d5748SToby Isaac } 126*130d5748SToby Isaac 127*130d5748SToby Isaac static PetscErrorCode PetscSpaceGetDimension_Ptrimmed(PetscSpace sp, PetscInt *dim) 128*130d5748SToby Isaac { 129*130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 130*130d5748SToby Isaac PetscInt f; 131*130d5748SToby Isaac PetscInt Nf; 132*130d5748SToby Isaac PetscErrorCode ierr; 133*130d5748SToby Isaac 134*130d5748SToby Isaac PetscFunctionBegin; 135*130d5748SToby Isaac f = pt->formDegree; 136*130d5748SToby Isaac // For PetscSpace, degree refers to the largest complete polynomial degree contained in the space which 137*130d5748SToby Isaac // is equal to the index of a P trimmed space only for 0-forms: otherwise, the index is degree + 1 138*130d5748SToby Isaac ierr = PetscDTPTrimmedSize(sp->Nv, f == 0 ? sp->degree : sp->degree + 1, pt->formDegree, dim);CHKERRQ(ierr); 139*130d5748SToby Isaac ierr = PetscDTBinomialInt(sp->Nv, PetscAbsInt(pt->formDegree), &Nf);CHKERRQ(ierr); 140*130d5748SToby Isaac *dim *= (sp->Nc / Nf); 141*130d5748SToby Isaac PetscFunctionReturn(0); 142*130d5748SToby Isaac } 143*130d5748SToby Isaac 144*130d5748SToby Isaac /* 145*130d5748SToby Isaac p in [0, npoints), i in [0, pdim), c in [0, Nc) 146*130d5748SToby Isaac 147*130d5748SToby Isaac B[p][i][c] = B[p][i_scalar][c][c] 148*130d5748SToby Isaac */ 149*130d5748SToby Isaac static PetscErrorCode PetscSpaceEvaluate_Ptrimmed(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[]) 150*130d5748SToby Isaac { 151*130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 152*130d5748SToby Isaac DM dm = sp->dm; 153*130d5748SToby Isaac PetscInt jet, degree, Nf, Ncopies, Njet; 154*130d5748SToby Isaac PetscInt Nc = sp->Nc; 155*130d5748SToby Isaac PetscInt f; 156*130d5748SToby Isaac PetscInt dim = sp->Nv; 157*130d5748SToby Isaac PetscReal *eval; 158*130d5748SToby Isaac PetscInt Nb; 159*130d5748SToby Isaac PetscErrorCode ierr; 160*130d5748SToby Isaac 161*130d5748SToby Isaac PetscFunctionBegin; 162*130d5748SToby Isaac if (!pt->setupCalled) { 163*130d5748SToby Isaac ierr = PetscSpaceSetUp(sp);CHKERRQ(ierr); 164*130d5748SToby Isaac ierr = PetscSpaceEvaluate(sp, npoints, points, B, D, H);CHKERRQ(ierr); 165*130d5748SToby Isaac PetscFunctionReturn(0); 166*130d5748SToby Isaac } 167*130d5748SToby Isaac if (H) { 168*130d5748SToby Isaac jet = 2; 169*130d5748SToby Isaac } else if (D) { 170*130d5748SToby Isaac jet = 1; 171*130d5748SToby Isaac } else { 172*130d5748SToby Isaac jet = 0; 173*130d5748SToby Isaac } 174*130d5748SToby Isaac f = pt->formDegree; 175*130d5748SToby Isaac degree = f == 0 ? sp->degree : sp->degree + 1; 176*130d5748SToby Isaac ierr = PetscDTBinomialInt(dim, PetscAbsInt(f), &Nf);CHKERRQ(ierr); 177*130d5748SToby Isaac Ncopies = Nc / Nf; 178*130d5748SToby Isaac if (Ncopies != 1) SETERRQ(PetscObjectComm((PetscObject) sp), PETSC_ERR_PLIB, "Multicopy spaces should have been converted to PETSCSPACESUM"); 179*130d5748SToby Isaac ierr = PetscDTBinomialInt(dim + jet, dim, &Njet);CHKERRQ(ierr); 180*130d5748SToby Isaac ierr = PetscDTPTrimmedSize(dim, degree, f, &Nb);CHKERRQ(ierr); 181*130d5748SToby Isaac ierr = DMGetWorkArray(dm, Nb * Nf * Njet * npoints, MPIU_REAL, &eval);CHKERRQ(ierr); 182*130d5748SToby Isaac ierr = PetscDTPTrimmedEvalJet(dim, npoints, points, degree, f, jet, eval);CHKERRQ(ierr); 183*130d5748SToby Isaac if (B) { 184*130d5748SToby Isaac PetscInt p_strl = Nf*Nb; 185*130d5748SToby Isaac PetscInt b_strl = Nf; 186*130d5748SToby Isaac PetscInt v_strl = 1; 187*130d5748SToby Isaac 188*130d5748SToby Isaac PetscInt b_strr = Nf*Njet*npoints; 189*130d5748SToby Isaac PetscInt v_strr = Njet*npoints; 190*130d5748SToby Isaac PetscInt p_strr = 1; 191*130d5748SToby Isaac 192*130d5748SToby Isaac for (PetscInt v = 0; v < Nf; v++) { 193*130d5748SToby Isaac for (PetscInt b = 0; b < Nb; b++) { 194*130d5748SToby Isaac for (PetscInt p = 0; p < npoints; p++) { 195*130d5748SToby Isaac B[p*p_strl + b*b_strl + v*v_strl] = eval[b*b_strr + v*v_strr + p*p_strr]; 196*130d5748SToby Isaac } 197*130d5748SToby Isaac } 198*130d5748SToby Isaac } 199*130d5748SToby Isaac } 200*130d5748SToby Isaac if (D) { 201*130d5748SToby Isaac PetscInt p_strl = dim*Nb*Ncopies*Nc; 202*130d5748SToby Isaac PetscInt b_strl = dim*Nb*Nc; 203*130d5748SToby Isaac PetscInt c_strl = dim*(Nc + Nf); 204*130d5748SToby Isaac PetscInt v_strl = dim; 205*130d5748SToby Isaac PetscInt d_strl = 1; 206*130d5748SToby Isaac 207*130d5748SToby Isaac PetscInt b_strr = Nf*Njet*npoints; 208*130d5748SToby Isaac PetscInt v_strr = Njet*npoints; 209*130d5748SToby Isaac PetscInt d_strr = npoints; 210*130d5748SToby Isaac PetscInt p_strr = 1; 211*130d5748SToby Isaac 212*130d5748SToby Isaac for (PetscInt c = 0; c < Ncopies; c++) { 213*130d5748SToby Isaac for (PetscInt v = 0; v < Nf; v++) { 214*130d5748SToby Isaac for (PetscInt d = 0; d < dim; d++) { 215*130d5748SToby Isaac for (PetscInt b = 0; b < Nb; b++) { 216*130d5748SToby Isaac for (PetscInt p = 0; p < npoints; p++) { 217*130d5748SToby Isaac D[p*p_strl + b*b_strl + c*c_strl + v*v_strl + d*d_strl] = eval[b*b_strr + v*v_strr + (1+d)*d_strr + p*p_strr]; 218*130d5748SToby Isaac } 219*130d5748SToby Isaac } 220*130d5748SToby Isaac } 221*130d5748SToby Isaac } 222*130d5748SToby Isaac } 223*130d5748SToby Isaac } 224*130d5748SToby Isaac if (H) { 225*130d5748SToby Isaac PetscInt p_strl = dim*dim*Nb*Ncopies*Nc; 226*130d5748SToby Isaac PetscInt b_strl = dim*dim*Nb*Nc; 227*130d5748SToby Isaac PetscInt c_strl = dim*dim*(Nc + Nf); 228*130d5748SToby Isaac PetscInt v_strl = dim*dim*1; 229*130d5748SToby Isaac PetscInt d1_strl = dim; 230*130d5748SToby Isaac PetscInt d2_strl = 1; 231*130d5748SToby Isaac 232*130d5748SToby Isaac PetscInt b_strr = Nf*Njet*npoints; 233*130d5748SToby Isaac PetscInt v_strr = Njet*npoints; 234*130d5748SToby Isaac PetscInt j_strr = npoints; 235*130d5748SToby Isaac PetscInt p_strr = 1; 236*130d5748SToby Isaac 237*130d5748SToby Isaac PetscInt *derivs; 238*130d5748SToby Isaac ierr = PetscCalloc1(dim, &derivs);CHKERRQ(ierr); 239*130d5748SToby Isaac for (PetscInt d1 = 0; d1 < dim; d1++) { 240*130d5748SToby Isaac for (PetscInt d2 = 0; d2 < dim; d2++) { 241*130d5748SToby Isaac PetscInt j; 242*130d5748SToby Isaac derivs[d1]++; 243*130d5748SToby Isaac derivs[d2]++; 244*130d5748SToby Isaac ierr = PetscDTGradedOrderToIndex(dim, derivs, &j);CHKERRQ(ierr); 245*130d5748SToby Isaac derivs[d1]--; 246*130d5748SToby Isaac derivs[d2]--; 247*130d5748SToby Isaac for (PetscInt c = 0; c < Ncopies; c++) { 248*130d5748SToby Isaac for (PetscInt v = 0; v < Nf; v++) { 249*130d5748SToby Isaac for (PetscInt b = 0; b < Nb; b++) { 250*130d5748SToby Isaac for (PetscInt p = 0; p < npoints; p++) { 251*130d5748SToby Isaac H[p*p_strl + b*b_strl + c*c_strl + v*v_strl + d1*d1_strl + d2*d2_strl] = eval[b*b_strr + v*v_strr + j*j_strr + p*p_strr]; 252*130d5748SToby Isaac } 253*130d5748SToby Isaac } 254*130d5748SToby Isaac } 255*130d5748SToby Isaac } 256*130d5748SToby Isaac } 257*130d5748SToby Isaac } 258*130d5748SToby Isaac ierr = PetscFree(derivs);CHKERRQ(ierr); 259*130d5748SToby Isaac } 260*130d5748SToby Isaac ierr = DMRestoreWorkArray(dm, Nb * Nf * Njet * npoints, MPIU_REAL, &eval);CHKERRQ(ierr); 261*130d5748SToby Isaac PetscFunctionReturn(0); 262*130d5748SToby Isaac } 263*130d5748SToby Isaac 264*130d5748SToby Isaac /*@ 265*130d5748SToby Isaac PetscSpacePTrimmedSetFormDegree - Set the form degree of the trimmed polynomials. 266*130d5748SToby Isaac 267*130d5748SToby Isaac Input Parameters: 268*130d5748SToby Isaac + sp - the function space object 269*130d5748SToby Isaac - formDegree - the form degree 270*130d5748SToby Isaac 271*130d5748SToby Isaac Options Database: 272*130d5748SToby Isaac . -petscspace_ptrimmed_form_degree <int> - The trimmed polynomial form degree 273*130d5748SToby Isaac 274*130d5748SToby Isaac Level: intermediate 275*130d5748SToby Isaac 276*130d5748SToby Isaac .seealso: PetscDTAltV, PetscDTPTrimmedEvalJet(), PetscSpacePTrimmedGetFormDegree() 277*130d5748SToby Isaac @*/ 278*130d5748SToby Isaac PetscErrorCode PetscSpacePTrimmedSetFormDegree(PetscSpace sp, PetscInt formDegree) 279*130d5748SToby Isaac { 280*130d5748SToby Isaac PetscErrorCode ierr; 281*130d5748SToby Isaac 282*130d5748SToby Isaac PetscFunctionBegin; 283*130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 284*130d5748SToby Isaac ierr = PetscTryMethod(sp,"PetscSpacePTrimmedSetFormDegree_C",(PetscSpace,PetscInt),(sp,formDegree));CHKERRQ(ierr); 285*130d5748SToby Isaac PetscFunctionReturn(0); 286*130d5748SToby Isaac } 287*130d5748SToby Isaac 288*130d5748SToby Isaac /*@ 289*130d5748SToby Isaac PetscSpacePTrimmedGetFormDegree - Get the form degree of the trimmed polynomials. 290*130d5748SToby Isaac 291*130d5748SToby Isaac Input Parameters: 292*130d5748SToby Isaac . sp - the function space object 293*130d5748SToby Isaac 294*130d5748SToby Isaac Output Parameters: 295*130d5748SToby Isaac . formDegee - the form degree 296*130d5748SToby Isaac 297*130d5748SToby Isaac Level: intermediate 298*130d5748SToby Isaac 299*130d5748SToby Isaac .seealso: PetscDTAltV, PetscDTPTrimmedEvalJet(), PetscSpacePTrimmedSetFormDegree() 300*130d5748SToby Isaac @*/ 301*130d5748SToby Isaac PetscErrorCode PetscSpacePTrimmedGetFormDegree(PetscSpace sp, PetscInt *formDegree) 302*130d5748SToby Isaac { 303*130d5748SToby Isaac PetscErrorCode ierr; 304*130d5748SToby Isaac 305*130d5748SToby Isaac PetscFunctionBegin; 306*130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 307*130d5748SToby Isaac PetscValidPointer(formDegree, 2); 308*130d5748SToby Isaac ierr = PetscTryMethod(sp,"PetscSpacePTrimmedGetFormDegree_C",(PetscSpace,PetscInt*),(sp,formDegree));CHKERRQ(ierr); 309*130d5748SToby Isaac PetscFunctionReturn(0); 310*130d5748SToby Isaac } 311*130d5748SToby Isaac 312*130d5748SToby Isaac static PetscErrorCode PetscSpacePTrimmedSetFormDegree_Ptrimmed(PetscSpace sp, PetscInt formDegree) 313*130d5748SToby Isaac { 314*130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 315*130d5748SToby Isaac 316*130d5748SToby Isaac PetscFunctionBegin; 317*130d5748SToby Isaac pt->formDegree = formDegree; 318*130d5748SToby Isaac PetscFunctionReturn(0); 319*130d5748SToby Isaac } 320*130d5748SToby Isaac 321*130d5748SToby Isaac static PetscErrorCode PetscSpacePTrimmedGetFormDegree_Ptrimmed(PetscSpace sp, PetscInt *formDegree) 322*130d5748SToby Isaac { 323*130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 324*130d5748SToby Isaac 325*130d5748SToby Isaac PetscFunctionBegin; 326*130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 327*130d5748SToby Isaac PetscValidPointer(formDegree, 2); 328*130d5748SToby Isaac *formDegree = pt->formDegree; 329*130d5748SToby Isaac PetscFunctionReturn(0); 330*130d5748SToby Isaac } 331*130d5748SToby Isaac 332*130d5748SToby Isaac static PetscErrorCode PetscSpaceGetHeightSubspace_Ptrimmed(PetscSpace sp, PetscInt height, PetscSpace *subsp) 333*130d5748SToby Isaac { 334*130d5748SToby Isaac PetscSpace_Ptrimmed *pt = (PetscSpace_Ptrimmed *) sp->data; 335*130d5748SToby Isaac PetscInt dim; 336*130d5748SToby Isaac PetscErrorCode ierr; 337*130d5748SToby Isaac 338*130d5748SToby Isaac PetscFunctionBegin; 339*130d5748SToby Isaac ierr = PetscSpaceGetNumVariables(sp, &dim);CHKERRQ(ierr); 340*130d5748SToby Isaac if (height > dim || height < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Asked for space at height %D for dimension %D space", height, dim); 341*130d5748SToby Isaac if (!pt->subspaces) {ierr = PetscCalloc1(dim, &(pt->subspaces));CHKERRQ(ierr);} 342*130d5748SToby Isaac if ((dim - height) <= PetscAbsInt(pt->formDegree)) { 343*130d5748SToby Isaac if (!pt->subspaces[height-1]) { 344*130d5748SToby Isaac PetscInt Nc, degree, Nf, Ncopies, Nfsub; 345*130d5748SToby Isaac PetscSpace sub; 346*130d5748SToby Isaac const char *name; 347*130d5748SToby Isaac 348*130d5748SToby Isaac ierr = PetscSpaceGetNumComponents(sp, &Nc);CHKERRQ(ierr); 349*130d5748SToby Isaac ierr = PetscDTBinomialInt(dim, PetscAbsInt(pt->formDegree), &Nf);CHKERRQ(ierr); 350*130d5748SToby Isaac ierr = PetscDTBinomialInt((dim-height), PetscAbsInt(pt->formDegree), &Nfsub);CHKERRQ(ierr); 351*130d5748SToby Isaac Ncopies = Nf / Nc; 352*130d5748SToby Isaac ierr = PetscSpaceGetDegree(sp, °ree, NULL);CHKERRQ(ierr); 353*130d5748SToby Isaac 354*130d5748SToby Isaac ierr = PetscSpaceCreate(PetscObjectComm((PetscObject) sp), &sub);CHKERRQ(ierr); 355*130d5748SToby Isaac ierr = PetscObjectGetName((PetscObject) sp, &name);CHKERRQ(ierr); 356*130d5748SToby Isaac ierr = PetscObjectSetName((PetscObject) sub, name);CHKERRQ(ierr); 357*130d5748SToby Isaac ierr = PetscSpaceSetType(sub, PETSCSPACEPTRIMMED);CHKERRQ(ierr); 358*130d5748SToby Isaac ierr = PetscSpaceSetNumComponents(sub, Nfsub * Ncopies);CHKERRQ(ierr); 359*130d5748SToby Isaac ierr = PetscSpaceSetDegree(sub, degree, PETSC_DETERMINE);CHKERRQ(ierr); 360*130d5748SToby Isaac ierr = PetscSpaceSetNumVariables(sub, dim-height);CHKERRQ(ierr); 361*130d5748SToby Isaac ierr = PetscSpacePTrimmedSetFormDegree(sub, pt->formDegree);CHKERRQ(ierr); 362*130d5748SToby Isaac ierr = PetscSpaceSetUp(sub);CHKERRQ(ierr); 363*130d5748SToby Isaac pt->subspaces[height-1] = sub; 364*130d5748SToby Isaac } 365*130d5748SToby Isaac *subsp = pt->subspaces[height-1]; 366*130d5748SToby Isaac } else { 367*130d5748SToby Isaac *subsp = NULL; 368*130d5748SToby Isaac } 369*130d5748SToby Isaac PetscFunctionReturn(0); 370*130d5748SToby Isaac } 371*130d5748SToby Isaac 372*130d5748SToby Isaac static PetscErrorCode PetscSpaceInitialize_Ptrimmed(PetscSpace sp) 373*130d5748SToby Isaac { 374*130d5748SToby Isaac PetscErrorCode ierr; 375*130d5748SToby Isaac 376*130d5748SToby Isaac PetscFunctionBegin; 377*130d5748SToby Isaac ierr = PetscObjectComposeFunction((PetscObject) sp, "PetscSpacePTrimmedGetFormDegree_C", PetscSpacePTrimmedGetFormDegree_Ptrimmed);CHKERRQ(ierr); 378*130d5748SToby Isaac ierr = PetscObjectComposeFunction((PetscObject) sp, "PetscSpacePTrimmedSetFormDegree_C", PetscSpacePTrimmedSetFormDegree_Ptrimmed);CHKERRQ(ierr); 379*130d5748SToby Isaac sp->ops->setfromoptions = PetscSpaceSetFromOptions_Ptrimmed; 380*130d5748SToby Isaac sp->ops->setup = PetscSpaceSetUp_Ptrimmed; 381*130d5748SToby Isaac sp->ops->view = PetscSpaceView_Ptrimmed; 382*130d5748SToby Isaac sp->ops->destroy = PetscSpaceDestroy_Ptrimmed; 383*130d5748SToby Isaac sp->ops->getdimension = PetscSpaceGetDimension_Ptrimmed; 384*130d5748SToby Isaac sp->ops->evaluate = PetscSpaceEvaluate_Ptrimmed; 385*130d5748SToby Isaac sp->ops->getheightsubspace = PetscSpaceGetHeightSubspace_Ptrimmed; 386*130d5748SToby Isaac PetscFunctionReturn(0); 387*130d5748SToby Isaac } 388*130d5748SToby Isaac 389*130d5748SToby Isaac /*MC 390*130d5748SToby Isaac PETSCSPACEPTRIMMED = "ptrimmed" - A PetscSpace object that encapsulates a trimmed polynomial space. 391*130d5748SToby Isaac 392*130d5748SToby Isaac Level: intermediate 393*130d5748SToby Isaac 394*130d5748SToby Isaac .seealso: PetscSpaceType, PetscSpaceCreate(), PetscSpaceSetType(), PetscDTPTrimmedEvalJet() 395*130d5748SToby Isaac M*/ 396*130d5748SToby Isaac 397*130d5748SToby Isaac PETSC_EXTERN PetscErrorCode PetscSpaceCreate_Ptrimmed(PetscSpace sp) 398*130d5748SToby Isaac { 399*130d5748SToby Isaac PetscSpace_Ptrimmed *pt; 400*130d5748SToby Isaac PetscErrorCode ierr; 401*130d5748SToby Isaac 402*130d5748SToby Isaac PetscFunctionBegin; 403*130d5748SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 404*130d5748SToby Isaac ierr = PetscNewLog(sp,&pt);CHKERRQ(ierr); 405*130d5748SToby Isaac sp->data = pt; 406*130d5748SToby Isaac 407*130d5748SToby Isaac pt->subspaces = NULL; 408*130d5748SToby Isaac sp->Nc = PETSC_DETERMINE; 409*130d5748SToby Isaac 410*130d5748SToby Isaac ierr = PetscSpaceInitialize_Ptrimmed(sp);CHKERRQ(ierr); 411*130d5748SToby Isaac PetscFunctionReturn(0); 412*130d5748SToby Isaac } 413*130d5748SToby Isaac 414