xref: /petsc/src/dm/dt/space/impls/ptrimmed/spaceptrimmed.c (revision 130d574890c8251ed9f630c1bd2606bbbbfba458)
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, &deg, &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, &degree, 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