xref: /petsc/src/dm/dt/space/impls/sum/spacesum.c (revision b122ec5aa1bd4469eb4e0673542fb7de3f411254)
1d092c84bSBrandon Whitchurch #include <petsc/private/petscfeimpl.h> /*I "petscfe.h" I*/
2d092c84bSBrandon Whitchurch /*@
3d092c84bSBrandon Whitchurch   PetscSpaceSumGetNumSubspaces - Get the number of spaces in the sum
4d092c84bSBrandon Whitchurch 
5d092c84bSBrandon Whitchurch   Input Parameter:
6d092c84bSBrandon Whitchurch   . sp  - the function space object
7d092c84bSBrandon Whitchurch 
8d092c84bSBrandon Whitchurch   Output Parameter:
9d092c84bSBrandon Whitchurch   . numSumSpaces - the number of spaces
10d092c84bSBrandon Whitchurch 
11d092c84bSBrandon Whitchurch Level: intermediate
12d092c84bSBrandon Whitchurch 
13d092c84bSBrandon Whitchurch .seealso: PetscSpaceSumSetNumSubspaces(), PetscSpaceSetDegree(), PetscSpaceSetNumVariables()
14d092c84bSBrandon Whitchurch @*/
15d092c84bSBrandon Whitchurch PetscErrorCode PetscSpaceSumGetNumSubspaces(PetscSpace sp,PetscInt *numSumSpaces)
16d092c84bSBrandon Whitchurch {
17d092c84bSBrandon Whitchurch   PetscFunctionBegin;
18d092c84bSBrandon Whitchurch   PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1);
19d092c84bSBrandon Whitchurch   PetscValidIntPointer(numSumSpaces,2);
205f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscTryMethod(sp,"PetscSpaceSumGetNumSubspaces_C",(PetscSpace,PetscInt*),(sp,numSumSpaces)));
21d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
22d092c84bSBrandon Whitchurch }
23d092c84bSBrandon Whitchurch 
24d092c84bSBrandon Whitchurch /*@
25d092c84bSBrandon Whitchurch   PetscSpaceSumSetNumSubspaces - Set the number of spaces in the sum
26d092c84bSBrandon Whitchurch 
27d092c84bSBrandon Whitchurch   Input Parameters:
28d092c84bSBrandon Whitchurch   + sp  - the function space object
29d092c84bSBrandon Whitchurch   - numSumSpaces - the number of spaces
30d092c84bSBrandon Whitchurch 
31d092c84bSBrandon Whitchurch Level: intermediate
32d092c84bSBrandon Whitchurch 
33d092c84bSBrandon Whitchurch .seealso: PetscSpaceSumGetNumSubspaces(), PetscSpaceSetDegree(), PetscSpaceSetNumVariables()
34d092c84bSBrandon Whitchurch @*/
35d092c84bSBrandon Whitchurch PetscErrorCode PetscSpaceSumSetNumSubspaces(PetscSpace sp,PetscInt numSumSpaces)
36d092c84bSBrandon Whitchurch {
37d092c84bSBrandon Whitchurch   PetscFunctionBegin;
38d092c84bSBrandon Whitchurch   PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1);
395f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscTryMethod(sp,"PetscSpaceSumSetNumSubspaces_C",(PetscSpace,PetscInt),(sp,numSumSpaces)));
40d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
41d092c84bSBrandon Whitchurch }
42d092c84bSBrandon Whitchurch 
43d092c84bSBrandon Whitchurch /*@
44d092c84bSBrandon Whitchurch  PetscSpaceSumGetConcatenate - Get the concatenate flag for this space.
45d092c84bSBrandon Whitchurch  A concatenated sum space will have number of components equal to the sum of the number of components of all subspaces.A non-concatenated,
46d092c84bSBrandon Whitchurch  or direct sum space will have the same number of components as its subspaces .
47d092c84bSBrandon Whitchurch 
48d092c84bSBrandon Whitchurch  Input Parameters:
49d092c84bSBrandon Whitchurch  . sp - the function space object
50d092c84bSBrandon Whitchurch 
51d092c84bSBrandon Whitchurch  Output Parameters:
52d092c84bSBrandon Whitchurch  . concatenate - flag indicating whether subspaces are concatenated.
53d092c84bSBrandon Whitchurch 
54d092c84bSBrandon Whitchurch Level: intermediate
55d092c84bSBrandon Whitchurch 
56d092c84bSBrandon Whitchurch .seealso: PetscSpaceSumSetConcatenate()
57d092c84bSBrandon Whitchurch @*/
58d092c84bSBrandon Whitchurch PetscErrorCode PetscSpaceSumGetConcatenate(PetscSpace sp,PetscBool *concatenate)
59d092c84bSBrandon Whitchurch {
60d092c84bSBrandon Whitchurch   PetscFunctionBegin;
61d092c84bSBrandon Whitchurch   PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1);
625f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscTryMethod(sp,"PetscSpaceSumGetConcatenate_C",(PetscSpace,PetscBool*),(sp,concatenate)));
63d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
64d092c84bSBrandon Whitchurch }
65d092c84bSBrandon Whitchurch 
66d092c84bSBrandon Whitchurch /*@
67d092c84bSBrandon Whitchurch   PetscSpaceSumSetConcatenate - Sets the concatenate flag for this space.
68d092c84bSBrandon Whitchurch  A concatenated sum space will have number of components equal to the sum of the number of components of all subspaces.A non-concatenated,
69d092c84bSBrandon Whitchurch  or direct sum space will have the same number of components as its subspaces .
70d092c84bSBrandon Whitchurch 
71d092c84bSBrandon Whitchurch  Input Parameters:
72d092c84bSBrandon Whitchurch   + sp - the function space object
73d092c84bSBrandon Whitchurch   - concatenate - are subspaces concatenated components (true) or direct summands (false)
74d092c84bSBrandon Whitchurch 
75d092c84bSBrandon Whitchurch Level: intermediate
76d092c84bSBrandon Whitchurch .seealso: PetscSpaceSumGetConcatenate()
77d092c84bSBrandon Whitchurch @*/
78d092c84bSBrandon Whitchurch PetscErrorCode PetscSpaceSumSetConcatenate(PetscSpace sp,PetscBool concatenate)
79d092c84bSBrandon Whitchurch {
80d092c84bSBrandon Whitchurch   PetscFunctionBegin;
81d092c84bSBrandon Whitchurch   PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1);
825f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscTryMethod(sp,"PetscSpaceSumSetConcatenate_C",(PetscSpace,PetscBool),(sp,concatenate)));
83d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
84d092c84bSBrandon Whitchurch }
85d092c84bSBrandon Whitchurch 
86d092c84bSBrandon Whitchurch /*@
87d092c84bSBrandon Whitchurch   PetscSpaceSumGetSubspace - Get a space in the sum
88d092c84bSBrandon Whitchurch 
89d092c84bSBrandon Whitchurch   Input Parameters:
90d092c84bSBrandon Whitchurch   + sp - the function space object
91d092c84bSBrandon Whitchurch   - s  - The space number
92d092c84bSBrandon Whitchurch 
93d092c84bSBrandon Whitchurch   Output Parameter:
94d092c84bSBrandon Whitchurch   . subsp - the PetscSpace
95d092c84bSBrandon Whitchurch 
96d092c84bSBrandon Whitchurch Level: intermediate
97d092c84bSBrandon Whitchurch 
98d092c84bSBrandon Whitchurch .seealso: PetscSpaceSumSetSubspace(), PetscSpaceSetDegree(), PetscSpaceSetNumVariables()
99d092c84bSBrandon Whitchurch @*/
100d092c84bSBrandon Whitchurch PetscErrorCode PetscSpaceSumGetSubspace(PetscSpace sp,PetscInt s,PetscSpace *subsp)
101d092c84bSBrandon Whitchurch {
102d092c84bSBrandon Whitchurch   PetscFunctionBegin;
103d092c84bSBrandon Whitchurch   PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1);
104d092c84bSBrandon Whitchurch   PetscValidPointer(subsp,3);
1055f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscTryMethod(sp,"PetscSpaceSumGetSubspace_C",(PetscSpace,PetscInt,PetscSpace*),(sp,s,subsp)));
106d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
107d092c84bSBrandon Whitchurch }
108d092c84bSBrandon Whitchurch 
109d092c84bSBrandon Whitchurch /*@
110d092c84bSBrandon Whitchurch   PetscSpaceSumSetSubspace - Set a space in the sum
111d092c84bSBrandon Whitchurch 
112d092c84bSBrandon Whitchurch   Input Parameters:
113d092c84bSBrandon Whitchurch   + sp    - the function space object
114d092c84bSBrandon Whitchurch   . s     - The space number
115d092c84bSBrandon Whitchurch   - subsp - the number of spaces
116d092c84bSBrandon Whitchurch 
117d092c84bSBrandon Whitchurch Level: intermediate
118d092c84bSBrandon Whitchurch 
119d092c84bSBrandon Whitchurch .seealso: PetscSpaceSumGetSubspace(), PetscSpaceSetDegree(), PetscSpaceSetNumVariables()
120d092c84bSBrandon Whitchurch @*/
121d092c84bSBrandon Whitchurch PetscErrorCode PetscSpaceSumSetSubspace(PetscSpace sp,PetscInt s,PetscSpace subsp)
122d092c84bSBrandon Whitchurch {
123d092c84bSBrandon Whitchurch   PetscFunctionBegin;
124d092c84bSBrandon Whitchurch   PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1);
125d092c84bSBrandon Whitchurch   if (subsp) PetscValidHeaderSpecific(subsp,PETSCSPACE_CLASSID,3);
1265f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscTryMethod(sp,"PetscSpaceSumSetSubspace_C",(PetscSpace,PetscInt,PetscSpace),(sp,s,subsp)));
127d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
128d092c84bSBrandon Whitchurch }
129d092c84bSBrandon Whitchurch 
130d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumGetNumSubspaces_Sum(PetscSpace space,PetscInt *numSumSpaces)
131d092c84bSBrandon Whitchurch {
132d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum = (PetscSpace_Sum*)space->data;
133d092c84bSBrandon Whitchurch 
134d092c84bSBrandon Whitchurch   PetscFunctionBegin;
135d092c84bSBrandon Whitchurch   *numSumSpaces = sum->numSumSpaces;
136d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
137d092c84bSBrandon Whitchurch }
138d092c84bSBrandon Whitchurch 
139d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumSetNumSubspaces_Sum(PetscSpace space,PetscInt numSumSpaces)
140d092c84bSBrandon Whitchurch {
141d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum = (PetscSpace_Sum*)space->data;
142d092c84bSBrandon Whitchurch   PetscInt       Ns   = sum->numSumSpaces;
143d092c84bSBrandon Whitchurch 
144d092c84bSBrandon Whitchurch   PetscFunctionBegin;
14528b400f6SJacob Faibussowitsch   PetscCheck(!sum->setupCalled,PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_WRONGSTATE,"Cannot change number of subspaces after setup called");
146d092c84bSBrandon Whitchurch   if (numSumSpaces == Ns) PetscFunctionReturn(0);
147d092c84bSBrandon Whitchurch   if (Ns >= 0) {
148d092c84bSBrandon Whitchurch     PetscInt s;
149d092c84bSBrandon Whitchurch     for (s=0; s<Ns; ++s) {
1505f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscSpaceDestroy(&sum->sumspaces[s]));
151d092c84bSBrandon Whitchurch     }
1525f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscFree(sum->sumspaces));
153d092c84bSBrandon Whitchurch   }
154d092c84bSBrandon Whitchurch 
155d092c84bSBrandon Whitchurch   Ns   = sum->numSumSpaces = numSumSpaces;
1565f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCalloc1(Ns,&sum->sumspaces));
157d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
158d092c84bSBrandon Whitchurch }
159d092c84bSBrandon Whitchurch 
160d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumGetConcatenate_Sum(PetscSpace sp,PetscBool *concatenate)
161d092c84bSBrandon Whitchurch {
162d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data;
163d092c84bSBrandon Whitchurch 
164d092c84bSBrandon Whitchurch   PetscFunctionBegin;
165d092c84bSBrandon Whitchurch   *concatenate = sum->concatenate;
166d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
167d092c84bSBrandon Whitchurch }
168d092c84bSBrandon Whitchurch 
169d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumSetConcatenate_Sum(PetscSpace sp,PetscBool concatenate)
170d092c84bSBrandon Whitchurch {
171d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data;
172d092c84bSBrandon Whitchurch 
173d092c84bSBrandon Whitchurch   PetscFunctionBegin;
17428b400f6SJacob Faibussowitsch   PetscCheck(!sum->setupCalled,PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_WRONGSTATE,"Cannot change space concatenation after setup called.");
175d092c84bSBrandon Whitchurch 
176d092c84bSBrandon Whitchurch   sum->concatenate = concatenate;
177d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
178d092c84bSBrandon Whitchurch }
179d092c84bSBrandon Whitchurch 
180d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumGetSubspace_Sum(PetscSpace space,PetscInt s,PetscSpace *subspace)
181d092c84bSBrandon Whitchurch {
182d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum = (PetscSpace_Sum*)space->data;
183d092c84bSBrandon Whitchurch   PetscInt       Ns   = sum->numSumSpaces;
184d092c84bSBrandon Whitchurch 
185d092c84bSBrandon Whitchurch   PetscFunctionBegin;
1862c71b3e2SJacob Faibussowitsch   PetscCheckFalse(Ns < 0,PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_WRONGSTATE,"Must call PetscSpaceSumSetNumSubspaces() first");
1872c71b3e2SJacob Faibussowitsch   PetscCheckFalse(s<0 || s>=Ns,PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_OUTOFRANGE,"Invalid subspace number %D",subspace);
188d092c84bSBrandon Whitchurch 
189d092c84bSBrandon Whitchurch   *subspace = sum->sumspaces[s];
190d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
191d092c84bSBrandon Whitchurch }
192d092c84bSBrandon Whitchurch 
193d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumSetSubspace_Sum(PetscSpace space,PetscInt s,PetscSpace subspace)
194d092c84bSBrandon Whitchurch {
195d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum = (PetscSpace_Sum*)space->data;
196d092c84bSBrandon Whitchurch   PetscInt       Ns   = sum->numSumSpaces;
197d092c84bSBrandon Whitchurch 
198d092c84bSBrandon Whitchurch   PetscFunctionBegin;
19928b400f6SJacob Faibussowitsch   PetscCheck(!sum->setupCalled,PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_WRONGSTATE,"Cannot change subspace after setup called");
2002c71b3e2SJacob Faibussowitsch   PetscCheckFalse(Ns < 0,PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_WRONGSTATE,"Must call PetscSpaceSumSetNumSubspaces() first");
2012c71b3e2SJacob Faibussowitsch   PetscCheckFalse(s < 0 || s >= Ns,PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_OUTOFRANGE,"Invalid subspace number %D",subspace);
202d092c84bSBrandon Whitchurch 
2035f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectReference((PetscObject)subspace));
2045f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceDestroy(&sum->sumspaces[s]));
205d092c84bSBrandon Whitchurch   sum->sumspaces[s] = subspace;
206d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
207d092c84bSBrandon Whitchurch }
208d092c84bSBrandon Whitchurch 
209d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSetFromOptions_Sum(PetscOptionItems *PetscOptionsObject,PetscSpace sp)
210d092c84bSBrandon Whitchurch {
211d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data;
212d092c84bSBrandon Whitchurch   PetscInt       Ns,Nc,Nv,deg,i;
213d092c84bSBrandon Whitchurch   PetscBool      concatenate = PETSC_TRUE;
214d092c84bSBrandon Whitchurch   const char     *prefix;
215d092c84bSBrandon Whitchurch 
216d092c84bSBrandon Whitchurch   PetscFunctionBegin;
2175f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceGetNumVariables(sp,&Nv));
218d092c84bSBrandon Whitchurch   if (!Nv) PetscFunctionReturn(0);
2195f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceGetNumComponents(sp,&Nc));
2205f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceSumGetNumSubspaces(sp,&Ns));
2215f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceGetDegree(sp,&deg,NULL));
222d092c84bSBrandon Whitchurch   Ns   = (Ns == PETSC_DEFAULT) ? 1 : Ns;
223d092c84bSBrandon Whitchurch 
2245f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsHead(PetscOptionsObject,"PetscSpace sum options"));
2255f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsBoundedInt("-petscspace_sum_spaces","The number of subspaces","PetscSpaceSumSetNumSubspaces",Ns,&Ns,NULL,0));
226*b122ec5aSJacob Faibussowitsch   CHKERRQ(PetscOptionsBool("-petscspace_sum_concatenate","Subspaces are concatenated components of the final space","PetscSpaceSumSetFromOptions",
227*b122ec5aSJacob Faibussowitsch                            concatenate,&concatenate,NULL));
2285f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsTail());
229d092c84bSBrandon Whitchurch 
2302c71b3e2SJacob Faibussowitsch   PetscCheckFalse(Ns < 0 || (Nv > 0 && Ns == 0),PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Cannot have a sum space of %D spaces",Ns);
231d092c84bSBrandon Whitchurch   if (Ns != sum->numSumSpaces) {
2325f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceSumSetNumSubspaces(sp,Ns));
233d092c84bSBrandon Whitchurch   }
2345f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectGetOptionsPrefix((PetscObject)sp,&prefix));
235d092c84bSBrandon Whitchurch   for (i=0; i<Ns; ++i) {
236d092c84bSBrandon Whitchurch     PetscInt   sNv;
237d092c84bSBrandon Whitchurch     PetscSpace subspace;
238d092c84bSBrandon Whitchurch 
2395f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceSumGetSubspace(sp,i,&subspace));
240d092c84bSBrandon Whitchurch     if (!subspace) {
241d092c84bSBrandon Whitchurch       char subspacePrefix[256];
242d092c84bSBrandon Whitchurch 
2435f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscSpaceCreate(PetscObjectComm((PetscObject)sp),&subspace));
2445f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscObjectSetOptionsPrefix((PetscObject)subspace,prefix));
2455f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscSNPrintf(subspacePrefix,256,"sumcomp_%D_",i));
2465f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscObjectAppendOptionsPrefix((PetscObject)subspace,subspacePrefix));
247d092c84bSBrandon Whitchurch     } else {
2485f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscObjectReference((PetscObject)subspace));
249d092c84bSBrandon Whitchurch     }
2505f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceSetFromOptions(subspace));
2515f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceGetNumVariables(subspace,&sNv));
25228b400f6SJacob Faibussowitsch     PetscCheck(sNv,PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_WRONGSTATE,"Subspace %D has not been set properly, number of variables is 0.",i);
2535f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceSumSetSubspace(sp,i,subspace));
2545f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceDestroy(&subspace));
255d092c84bSBrandon Whitchurch   }
256d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
257d092c84bSBrandon Whitchurch }
258d092c84bSBrandon Whitchurch 
259d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSetUp_Sum(PetscSpace sp)
260d092c84bSBrandon Whitchurch {
261d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data;
262d092c84bSBrandon Whitchurch   PetscBool      concatenate = PETSC_TRUE;
263642c7897SToby Isaac   PetscBool      uniform;
264642c7897SToby Isaac   PetscInt       Nv,Ns,Nc,i,sum_Nc = 0,deg = PETSC_MAX_INT,maxDeg = PETSC_MIN_INT;
265642c7897SToby Isaac   PetscInt       minNc,maxNc;
266d092c84bSBrandon Whitchurch 
267d092c84bSBrandon Whitchurch   PetscFunctionBegin;
268d092c84bSBrandon Whitchurch   if (sum->setupCalled) PetscFunctionReturn(0);
269d092c84bSBrandon Whitchurch 
2705f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceGetNumVariables(sp,&Nv));
2715f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceGetNumComponents(sp,&Nc));
2725f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceSumGetNumSubspaces(sp,&Ns));
273d092c84bSBrandon Whitchurch   if (Ns == PETSC_DEFAULT) {
274d092c84bSBrandon Whitchurch     Ns   = 1;
2755f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceSumSetNumSubspaces(sp,Ns));
276d092c84bSBrandon Whitchurch   }
2772c71b3e2SJacob Faibussowitsch   PetscCheckFalse(Ns < 0,PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Cannot have %D subspaces", Ns);
278642c7897SToby Isaac   uniform = PETSC_TRUE;
279642c7897SToby Isaac   if (Ns) {
280642c7897SToby Isaac     PetscSpace s0;
281d092c84bSBrandon Whitchurch 
2825f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceSumGetSubspace(sp,0,&s0));
283642c7897SToby Isaac     for (PetscInt i = 1; i < Ns; i++) {
284642c7897SToby Isaac       PetscSpace si;
285642c7897SToby Isaac 
2865f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscSpaceSumGetSubspace(sp,i,&si));
287642c7897SToby Isaac       if (si != s0) {
288642c7897SToby Isaac         uniform = PETSC_FALSE;
289642c7897SToby Isaac         break;
290642c7897SToby Isaac       }
291642c7897SToby Isaac     }
292642c7897SToby Isaac   }
293642c7897SToby Isaac 
294642c7897SToby Isaac   minNc = Nc;
295642c7897SToby Isaac   maxNc = Nc;
296d092c84bSBrandon Whitchurch   for (i=0; i<Ns; ++i) {
297d092c84bSBrandon Whitchurch     PetscInt   sNv,sNc,iDeg,iMaxDeg;
298d092c84bSBrandon Whitchurch     PetscSpace si;
299d092c84bSBrandon Whitchurch 
3005f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceSumGetSubspace(sp,i,&si));
3015f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceSetUp(si));
3025f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceGetNumVariables(si,&sNv));
3032c71b3e2SJacob Faibussowitsch     PetscCheckFalse(sNv != Nv,PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_WRONGSTATE,"Subspace %D has %D variables, space has %D.",i,sNv,Nv);
3045f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceGetNumComponents(si,&sNc));
305d092c84bSBrandon Whitchurch     if (i == 0 && sNc == Nc) concatenate = PETSC_FALSE;
306642c7897SToby Isaac     minNc = PetscMin(minNc, sNc);
307642c7897SToby Isaac     maxNc = PetscMax(maxNc, sNc);
308d092c84bSBrandon Whitchurch     sum_Nc += sNc;
3095f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceSumGetSubspace(sp,i,&si));
3105f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceGetDegree(si,&iDeg,&iMaxDeg));
311642c7897SToby Isaac     deg     = PetscMin(deg,iDeg);
312d092c84bSBrandon Whitchurch     maxDeg  = PetscMax(maxDeg,iMaxDeg);
313d092c84bSBrandon Whitchurch   }
314d092c84bSBrandon Whitchurch 
315d092c84bSBrandon Whitchurch   if (concatenate) {
316d092c84bSBrandon Whitchurch     if (sum_Nc != Nc) {
31798921bdaSJacob Faibussowitsch       SETERRQ(PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Total number of subspace components (%D) does not match number of target space components (%D).",sum_Nc,Nc);
318d092c84bSBrandon Whitchurch     }
319d092c84bSBrandon Whitchurch   } else {
3202c71b3e2SJacob Faibussowitsch     PetscCheckFalse(minNc != Nc || maxNc != Nc,PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Subspaces must have same number of components as the target space.");
321d092c84bSBrandon Whitchurch   }
322d092c84bSBrandon Whitchurch 
323d092c84bSBrandon Whitchurch   sp->degree       = deg;
324d092c84bSBrandon Whitchurch   sp->maxDegree    = maxDeg;
325d092c84bSBrandon Whitchurch   sum->concatenate = concatenate;
326642c7897SToby Isaac   sum->uniform     = uniform;
327d092c84bSBrandon Whitchurch   sum->setupCalled = PETSC_TRUE;
328d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
329d092c84bSBrandon Whitchurch }
330d092c84bSBrandon Whitchurch 
331d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumView_Ascii(PetscSpace sp,PetscViewer v)
332d092c84bSBrandon Whitchurch {
333d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data;
334d092c84bSBrandon Whitchurch   PetscBool      concatenate = sum->concatenate;
335d092c84bSBrandon Whitchurch   PetscInt       i,Ns         = sum->numSumSpaces;
336d092c84bSBrandon Whitchurch 
337d092c84bSBrandon Whitchurch   PetscFunctionBegin;
338d092c84bSBrandon Whitchurch   if (concatenate) {
3395f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(v,"Sum space of %D concatenated subspaces%s\n",Ns, sum->uniform ? " (all identical)": ""));
340d092c84bSBrandon Whitchurch   } else {
3415f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(v,"Sum space of %D subspaces%s\n",Ns, sum->uniform ? " (all identical)" : ""));
342d092c84bSBrandon Whitchurch   }
343642c7897SToby Isaac   for (i=0; i < (sum->uniform ? (Ns > 0 ? 1 : 0) : Ns); ++i) {
3445f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPushTab(v));
3455f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceView(sum->sumspaces[i],v));
3465f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPopTab(v));
347d092c84bSBrandon Whitchurch   }
348d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
349d092c84bSBrandon Whitchurch }
350d092c84bSBrandon Whitchurch 
351d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceView_Sum(PetscSpace sp,PetscViewer viewer)
352d092c84bSBrandon Whitchurch {
353d092c84bSBrandon Whitchurch   PetscBool      iascii;
354d092c84bSBrandon Whitchurch 
355d092c84bSBrandon Whitchurch   PetscFunctionBegin;
3565f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
357d092c84bSBrandon Whitchurch   if (iascii) {
3585f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceSumView_Ascii(sp,viewer));
359d092c84bSBrandon Whitchurch   }
360d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
361d092c84bSBrandon Whitchurch }
362d092c84bSBrandon Whitchurch 
363d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceDestroy_Sum(PetscSpace sp)
364d092c84bSBrandon Whitchurch {
365d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data;
366d092c84bSBrandon Whitchurch   PetscInt       i,Ns   = sum->numSumSpaces;
367d092c84bSBrandon Whitchurch 
368d092c84bSBrandon Whitchurch   PetscFunctionBegin;
369d092c84bSBrandon Whitchurch   for (i=0; i<Ns; ++i) {
3705f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceDestroy(&sum->sumspaces[i]));
371d092c84bSBrandon Whitchurch   }
3725f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(sum->sumspaces));
373642c7897SToby Isaac   if (sum->heightsubspaces) {
374642c7897SToby Isaac     PetscInt d;
375642c7897SToby Isaac 
376642c7897SToby Isaac     /* sp->Nv is the spatial dimension, so it is equal to the number
377642c7897SToby Isaac      * of subspaces on higher co-dimension points */
378642c7897SToby Isaac     for (d = 0; d < sp->Nv; ++d) {
3795f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscSpaceDestroy(&sum->heightsubspaces[d]));
380642c7897SToby Isaac     }
381642c7897SToby Isaac   }
3825f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(sum->heightsubspaces));
3835f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetSubspace_C",NULL));
3845f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetSubspace_C",NULL));
3855f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetNumSubspaces_C",NULL));
3865f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetNumSubspaces_C",NULL));
3875f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(sum));
388d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
389d092c84bSBrandon Whitchurch }
390d092c84bSBrandon Whitchurch 
391d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceGetDimension_Sum(PetscSpace sp,PetscInt *dim)
392d092c84bSBrandon Whitchurch {
393d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data;
394d092c84bSBrandon Whitchurch   PetscInt       i,d = 0,Ns = sum->numSumSpaces;
395d092c84bSBrandon Whitchurch 
396d092c84bSBrandon Whitchurch   PetscFunctionBegin;
397642c7897SToby Isaac   if (!sum->setupCalled) {
3985f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceSetUp(sp));
3995f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceGetDimension(sp, dim));
400642c7897SToby Isaac     PetscFunctionReturn(0);
401642c7897SToby Isaac   }
402d092c84bSBrandon Whitchurch 
403d092c84bSBrandon Whitchurch   for (i=0; i<Ns; ++i) {
404d092c84bSBrandon Whitchurch     PetscInt id;
405d092c84bSBrandon Whitchurch 
4065f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceGetDimension(sum->sumspaces[i],&id));
407d092c84bSBrandon Whitchurch     d   += id;
408d092c84bSBrandon Whitchurch   }
409d092c84bSBrandon Whitchurch 
410d092c84bSBrandon Whitchurch   *dim = d;
411d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
412d092c84bSBrandon Whitchurch }
413d092c84bSBrandon Whitchurch 
414d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceEvaluate_Sum(PetscSpace sp,PetscInt npoints,const PetscReal points[],PetscReal B[],PetscReal D[],PetscReal H[])
415d092c84bSBrandon Whitchurch {
416d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data;
417d092c84bSBrandon Whitchurch   PetscBool      concatenate = sum->concatenate;
418d092c84bSBrandon Whitchurch   DM             dm = sp->dm;
419d092c84bSBrandon Whitchurch   PetscInt       Nc = sp->Nc,Nv = sp->Nv,Ns = sum->numSumSpaces;
420d092c84bSBrandon Whitchurch   PetscInt       i,s,offset,ncoffset,pdimfull,numelB,numelD,numelH;
421d092c84bSBrandon Whitchurch   PetscReal      *sB = NULL,*sD = NULL,*sH = NULL;
422d092c84bSBrandon Whitchurch 
423d092c84bSBrandon Whitchurch   PetscFunctionBegin;
424d092c84bSBrandon Whitchurch   if (!sum->setupCalled) {
4255f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceSetUp(sp));
4265f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceEvaluate(sp, npoints, points, B, D, H));
427642c7897SToby Isaac     PetscFunctionReturn(0);
428d092c84bSBrandon Whitchurch   }
4295f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceGetDimension(sp,&pdimfull));
430d092c84bSBrandon Whitchurch   numelB = npoints*pdimfull*Nc;
431d092c84bSBrandon Whitchurch   numelD = numelB*Nv;
432d092c84bSBrandon Whitchurch   numelH = numelD*Nv;
433d092c84bSBrandon Whitchurch   if (B || D || H) {
4345f80ce2aSJacob Faibussowitsch     CHKERRQ(DMGetWorkArray(dm,numelB,MPIU_REAL,&sB));
435d092c84bSBrandon Whitchurch   }
436d092c84bSBrandon Whitchurch   if (D || H) {
4375f80ce2aSJacob Faibussowitsch     CHKERRQ(DMGetWorkArray(dm,numelD,MPIU_REAL,&sD));
438d092c84bSBrandon Whitchurch   }
439d092c84bSBrandon Whitchurch   if (H) {
4405f80ce2aSJacob Faibussowitsch     CHKERRQ(DMGetWorkArray(dm,numelH,MPIU_REAL,&sH));
441d092c84bSBrandon Whitchurch   }
442d092c84bSBrandon Whitchurch   if (B)
443d092c84bSBrandon Whitchurch     for (i=0; i<numelB; ++i) B[i] = 0.;
444d092c84bSBrandon Whitchurch   if (D)
445d092c84bSBrandon Whitchurch     for (i=0; i<numelD; ++i) D[i] = 0.;
446d092c84bSBrandon Whitchurch   if (H)
447d092c84bSBrandon Whitchurch     for (i=0; i<numelH; ++i) H[i] = 0.;
448d092c84bSBrandon Whitchurch 
449d092c84bSBrandon Whitchurch   for (s=0,offset=0,ncoffset=0; s<Ns; ++s) {
450d092c84bSBrandon Whitchurch     PetscInt sNv,spdim,sNc,p;
451d092c84bSBrandon Whitchurch 
4525f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceGetNumVariables(sum->sumspaces[s],&sNv));
4535f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceGetNumComponents(sum->sumspaces[s],&sNc));
4545f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceGetDimension(sum->sumspaces[s],&spdim));
4552c71b3e2SJacob Faibussowitsch     PetscCheckFalse(offset + spdim > pdimfull,PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Subspace dimensions exceed target space dimension.");
456642c7897SToby Isaac     if (s == 0 || !sum->uniform) {
4575f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscSpaceEvaluate(sum->sumspaces[s],npoints,points,sB,sD,sH));
458642c7897SToby Isaac     }
459d092c84bSBrandon Whitchurch     if (B || D || H) {
460d092c84bSBrandon Whitchurch       for (p=0; p<npoints; ++p) {
461d092c84bSBrandon Whitchurch         PetscInt j;
462d092c84bSBrandon Whitchurch 
463d092c84bSBrandon Whitchurch         for (j=0; j<spdim; ++j) {
464d092c84bSBrandon Whitchurch           PetscInt c;
465d092c84bSBrandon Whitchurch 
466d092c84bSBrandon Whitchurch           for (c=0; c<sNc; ++c) {
467d092c84bSBrandon Whitchurch             PetscInt compoffset,BInd,sBInd;
468d092c84bSBrandon Whitchurch 
469d092c84bSBrandon Whitchurch             compoffset = concatenate ? c+ncoffset : c;
470d092c84bSBrandon Whitchurch             BInd       = (p*pdimfull + j + offset)*Nc + compoffset;
471d092c84bSBrandon Whitchurch             sBInd      = (p*spdim + j)*sNc + c;
472642c7897SToby Isaac             if (B) B[BInd] = sB[sBInd];
473d092c84bSBrandon Whitchurch             if (D || H) {
474d092c84bSBrandon Whitchurch               PetscInt v;
475d092c84bSBrandon Whitchurch 
476d092c84bSBrandon Whitchurch               for (v=0; v<Nv; ++v) {
477d092c84bSBrandon Whitchurch                 PetscInt DInd,sDInd;
478d092c84bSBrandon Whitchurch 
479d092c84bSBrandon Whitchurch                 DInd  = BInd*Nv + v;
480d092c84bSBrandon Whitchurch                 sDInd = sBInd*Nv + v;
481642c7897SToby Isaac                 if (D) D[DInd] = sD[sDInd];
482d092c84bSBrandon Whitchurch                 if (H) {
483d092c84bSBrandon Whitchurch                   PetscInt v2;
484d092c84bSBrandon Whitchurch 
485d092c84bSBrandon Whitchurch                   for (v2=0; v2<Nv; ++v2) {
486d092c84bSBrandon Whitchurch                     PetscInt HInd,sHInd;
487d092c84bSBrandon Whitchurch 
488d092c84bSBrandon Whitchurch                     HInd    = DInd*Nv + v2;
489d092c84bSBrandon Whitchurch                     sHInd   = sDInd*Nv + v2;
490642c7897SToby Isaac                     H[HInd] = sH[sHInd];
491d092c84bSBrandon Whitchurch                   }
492d092c84bSBrandon Whitchurch                 }
493d092c84bSBrandon Whitchurch               }
494d092c84bSBrandon Whitchurch             }
495d092c84bSBrandon Whitchurch           }
496d092c84bSBrandon Whitchurch         }
497d092c84bSBrandon Whitchurch       }
498d092c84bSBrandon Whitchurch     }
499d092c84bSBrandon Whitchurch     offset   += spdim;
500d092c84bSBrandon Whitchurch     ncoffset += sNc;
501d092c84bSBrandon Whitchurch   }
502d092c84bSBrandon Whitchurch 
503d092c84bSBrandon Whitchurch   if (H) {
5045f80ce2aSJacob Faibussowitsch     CHKERRQ(DMRestoreWorkArray(dm,numelH,MPIU_REAL,&sH));
505d092c84bSBrandon Whitchurch   }
506d092c84bSBrandon Whitchurch   if (D || H) {
5075f80ce2aSJacob Faibussowitsch     CHKERRQ(DMRestoreWorkArray(dm,numelD,MPIU_REAL,&sD));
508d092c84bSBrandon Whitchurch   }
509d092c84bSBrandon Whitchurch   if (B || D || H) {
5105f80ce2aSJacob Faibussowitsch     CHKERRQ(DMRestoreWorkArray(dm,numelB,MPIU_REAL,&sB));
511d092c84bSBrandon Whitchurch   }
512d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
513d092c84bSBrandon Whitchurch }
514d092c84bSBrandon Whitchurch 
515642c7897SToby Isaac static PetscErrorCode PetscSpaceGetHeightSubspace_Sum(PetscSpace sp, PetscInt height, PetscSpace *subsp)
516642c7897SToby Isaac {
517642c7897SToby Isaac   PetscSpace_Sum  *sum = (PetscSpace_Sum *) sp->data;
518642c7897SToby Isaac   PetscInt         Nc, dim, order;
519642c7897SToby Isaac   PetscBool        tensor;
520642c7897SToby Isaac 
521642c7897SToby Isaac   PetscFunctionBegin;
5225f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceGetNumComponents(sp, &Nc));
5235f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceGetNumVariables(sp, &dim));
5245f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceGetDegree(sp, &order, NULL));
5255f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpacePolynomialGetTensor(sp, &tensor));
5262c71b3e2SJacob Faibussowitsch   PetscCheckFalse(height > dim || height < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Asked for space at height %D for dimension %D space", height, dim);
5275f80ce2aSJacob Faibussowitsch   if (!sum->heightsubspaces) CHKERRQ(PetscCalloc1(dim, &sum->heightsubspaces));
528642c7897SToby Isaac   if (height <= dim) {
529642c7897SToby Isaac     if (!sum->heightsubspaces[height-1]) {
530642c7897SToby Isaac       PetscSpace  sub;
531642c7897SToby Isaac       const char *name;
532642c7897SToby Isaac 
5335f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscSpaceCreate(PetscObjectComm((PetscObject) sp), &sub));
5345f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscObjectGetName((PetscObject) sp,  &name));
5355f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscObjectSetName((PetscObject) sub,  name));
5365f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscSpaceSetType(sub, PETSCSPACESUM));
5375f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscSpaceSumSetNumSubspaces(sub, sum->numSumSpaces));
5385f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscSpaceSumSetConcatenate(sub, sum->concatenate));
5395f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscSpaceSetNumComponents(sub, Nc));
5405f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscSpaceSetNumVariables(sub, dim-height));
541642c7897SToby Isaac       for (PetscInt i = 0; i < sum->numSumSpaces; i++) {
542642c7897SToby Isaac         PetscSpace subh;
543642c7897SToby Isaac 
5445f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscSpaceGetHeightSubspace(sum->sumspaces[i], height, &subh));
5455f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscSpaceSumSetSubspace(sub, i, subh));
546642c7897SToby Isaac       }
5475f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscSpaceSetUp(sub));
548642c7897SToby Isaac       sum->heightsubspaces[height-1] = sub;
549642c7897SToby Isaac     }
550642c7897SToby Isaac     *subsp = sum->heightsubspaces[height-1];
551642c7897SToby Isaac   } else {
552642c7897SToby Isaac     *subsp = NULL;
553642c7897SToby Isaac   }
554642c7897SToby Isaac   PetscFunctionReturn(0);
555642c7897SToby Isaac }
556642c7897SToby Isaac 
557d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceInitialize_Sum(PetscSpace sp)
558d092c84bSBrandon Whitchurch {
559d092c84bSBrandon Whitchurch   PetscFunctionBegin;
560d092c84bSBrandon Whitchurch   sp->ops->setfromoptions    = PetscSpaceSetFromOptions_Sum;
561d092c84bSBrandon Whitchurch   sp->ops->setup             = PetscSpaceSetUp_Sum;
562d092c84bSBrandon Whitchurch   sp->ops->view              = PetscSpaceView_Sum;
563d092c84bSBrandon Whitchurch   sp->ops->destroy           = PetscSpaceDestroy_Sum;
564d092c84bSBrandon Whitchurch   sp->ops->getdimension      = PetscSpaceGetDimension_Sum;
565d092c84bSBrandon Whitchurch   sp->ops->evaluate          = PetscSpaceEvaluate_Sum;
566642c7897SToby Isaac   sp->ops->getheightsubspace = PetscSpaceGetHeightSubspace_Sum;
567d092c84bSBrandon Whitchurch 
5685f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetNumSubspaces_C",PetscSpaceSumGetNumSubspaces_Sum));
5695f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetNumSubspaces_C",PetscSpaceSumSetNumSubspaces_Sum));
5705f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetSubspace_C",PetscSpaceSumGetSubspace_Sum));
5715f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetSubspace_C",PetscSpaceSumSetSubspace_Sum));
5725f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetConcatenate_C",PetscSpaceSumGetConcatenate_Sum));
5735f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetConcatenate_C",PetscSpaceSumSetConcatenate_Sum));
574d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
575d092c84bSBrandon Whitchurch }
576d092c84bSBrandon Whitchurch 
577d092c84bSBrandon Whitchurch /*MC
578d092c84bSBrandon Whitchurch   PETSCSPACESUM = "sum" - A PetscSpace object that encapsulates a sum of subspaces.
579d092c84bSBrandon Whitchurch   That sum can either be direct or concatenate a concatenation.For example if A and B are spaces each with 2 components,
580d092c84bSBrandon Whitchurch   the direct sum of A and B will also have 2 components while the concatenated sum will have 4 components.In both cases A and B must be defined over the
581d092c84bSBrandon Whitchurch   same number of variables.
582d092c84bSBrandon Whitchurch 
583d092c84bSBrandon Whitchurch Level: intermediate
584d092c84bSBrandon Whitchurch 
585d092c84bSBrandon Whitchurch .seealso: PetscSpaceType, PetscSpaceCreate(), PetscSpaceSetType()
586d092c84bSBrandon Whitchurch M*/
587d092c84bSBrandon Whitchurch PETSC_EXTERN PetscErrorCode PetscSpaceCreate_Sum(PetscSpace sp)
588d092c84bSBrandon Whitchurch {
589d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum;
590d092c84bSBrandon Whitchurch 
591d092c84bSBrandon Whitchurch   PetscFunctionBegin;
592d092c84bSBrandon Whitchurch   PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1);
5935f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscNewLog(sp,&sum));
594642c7897SToby Isaac   sum->numSumSpaces = PETSC_DEFAULT;
595d092c84bSBrandon Whitchurch   sp->data = sum;
5965f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceInitialize_Sum(sp));
597d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
598d092c84bSBrandon Whitchurch }
599d092c84bSBrandon Whitchurch 
600d092c84bSBrandon Whitchurch PETSC_EXTERN PetscErrorCode PetscSpaceCreateSum(PetscInt numSubspaces,const PetscSpace subspaces[],PetscBool concatenate,PetscSpace *sumSpace)
601d092c84bSBrandon Whitchurch {
602d092c84bSBrandon Whitchurch   PetscInt       i,Nv,Nc = 0;
603d092c84bSBrandon Whitchurch 
604d092c84bSBrandon Whitchurch   PetscFunctionBegin;
605d092c84bSBrandon Whitchurch   if (sumSpace) {
6065f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceDestroy(sumSpace));
607d092c84bSBrandon Whitchurch   }
6085f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceCreate(PetscObjectComm((PetscObject)subspaces[0]),sumSpace));
6095f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceSetType(*sumSpace,PETSCSPACESUM));
6105f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceSumSetNumSubspaces(*sumSpace,numSubspaces));
6115f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceSumSetConcatenate(*sumSpace,concatenate));
612d092c84bSBrandon Whitchurch   for (i=0; i<numSubspaces; ++i) {
613d092c84bSBrandon Whitchurch     PetscInt sNc;
614d092c84bSBrandon Whitchurch 
6155f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceSumSetSubspace(*sumSpace,i,subspaces[i]));
6165f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSpaceGetNumComponents(subspaces[i],&sNc));
617d092c84bSBrandon Whitchurch     if (concatenate) Nc += sNc;
618d092c84bSBrandon Whitchurch     else Nc = sNc;
619d092c84bSBrandon Whitchurch   }
6205f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceGetNumVariables(subspaces[0],&Nv));
6215f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceSetNumComponents(*sumSpace,Nc));
6225f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceSetNumVariables(*sumSpace,Nv));
6235f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceSetUp(*sumSpace));
624d092c84bSBrandon Whitchurch 
625d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
626d092c84bSBrandon Whitchurch }
627