xref: /petsc/src/dm/dt/space/impls/sum/spacesum.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
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 
13db781477SPatrick Sanan .seealso: `PetscSpaceSumSetNumSubspaces()`, `PetscSpaceSetDegree()`, `PetscSpaceSetNumVariables()`
14d092c84bSBrandon Whitchurch @*/
159371c9d4SSatish Balay PetscErrorCode PetscSpaceSumGetNumSubspaces(PetscSpace sp, PetscInt *numSumSpaces) {
16d092c84bSBrandon Whitchurch   PetscFunctionBegin;
17d092c84bSBrandon Whitchurch   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
18d092c84bSBrandon Whitchurch   PetscValidIntPointer(numSumSpaces, 2);
19cac4c232SBarry Smith   PetscTryMethod(sp, "PetscSpaceSumGetNumSubspaces_C", (PetscSpace, PetscInt *), (sp, numSumSpaces));
20d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
21d092c84bSBrandon Whitchurch }
22d092c84bSBrandon Whitchurch 
23d092c84bSBrandon Whitchurch /*@
24d092c84bSBrandon Whitchurch   PetscSpaceSumSetNumSubspaces - Set the number of spaces in the sum
25d092c84bSBrandon Whitchurch 
26d092c84bSBrandon Whitchurch   Input Parameters:
27d092c84bSBrandon Whitchurch + sp  - the function space object
28d092c84bSBrandon Whitchurch - numSumSpaces - the number of spaces
29d092c84bSBrandon Whitchurch 
30d092c84bSBrandon Whitchurch Level: intermediate
31d092c84bSBrandon Whitchurch 
32db781477SPatrick Sanan .seealso: `PetscSpaceSumGetNumSubspaces()`, `PetscSpaceSetDegree()`, `PetscSpaceSetNumVariables()`
33d092c84bSBrandon Whitchurch @*/
349371c9d4SSatish Balay PetscErrorCode PetscSpaceSumSetNumSubspaces(PetscSpace sp, PetscInt numSumSpaces) {
35d092c84bSBrandon Whitchurch   PetscFunctionBegin;
36d092c84bSBrandon Whitchurch   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
37cac4c232SBarry Smith   PetscTryMethod(sp, "PetscSpaceSumSetNumSubspaces_C", (PetscSpace, PetscInt), (sp, numSumSpaces));
38d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
39d092c84bSBrandon Whitchurch }
40d092c84bSBrandon Whitchurch 
41d092c84bSBrandon Whitchurch /*@
42d092c84bSBrandon Whitchurch  PetscSpaceSumGetConcatenate - Get the concatenate flag for this space.
43d092c84bSBrandon 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,
44d092c84bSBrandon Whitchurch  or direct sum space will have the same number of components as its subspaces .
45d092c84bSBrandon Whitchurch 
46d092c84bSBrandon Whitchurch  Input Parameters:
47d092c84bSBrandon Whitchurch . sp - the function space object
48d092c84bSBrandon Whitchurch 
49d092c84bSBrandon Whitchurch  Output Parameters:
50d092c84bSBrandon Whitchurch . concatenate - flag indicating whether subspaces are concatenated.
51d092c84bSBrandon Whitchurch 
52d092c84bSBrandon Whitchurch Level: intermediate
53d092c84bSBrandon Whitchurch 
54db781477SPatrick Sanan .seealso: `PetscSpaceSumSetConcatenate()`
55d092c84bSBrandon Whitchurch @*/
569371c9d4SSatish Balay PetscErrorCode PetscSpaceSumGetConcatenate(PetscSpace sp, PetscBool *concatenate) {
57d092c84bSBrandon Whitchurch   PetscFunctionBegin;
58d092c84bSBrandon Whitchurch   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
59cac4c232SBarry Smith   PetscTryMethod(sp, "PetscSpaceSumGetConcatenate_C", (PetscSpace, PetscBool *), (sp, concatenate));
60d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
61d092c84bSBrandon Whitchurch }
62d092c84bSBrandon Whitchurch 
63d092c84bSBrandon Whitchurch /*@
64d092c84bSBrandon Whitchurch   PetscSpaceSumSetConcatenate - Sets the concatenate flag for this space.
65d092c84bSBrandon 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,
66d092c84bSBrandon Whitchurch  or direct sum space will have the same number of components as its subspaces .
67d092c84bSBrandon Whitchurch 
68d092c84bSBrandon Whitchurch  Input Parameters:
69d092c84bSBrandon Whitchurch + sp - the function space object
70d092c84bSBrandon Whitchurch - concatenate - are subspaces concatenated components (true) or direct summands (false)
71d092c84bSBrandon Whitchurch 
72d092c84bSBrandon Whitchurch Level: intermediate
73db781477SPatrick Sanan .seealso: `PetscSpaceSumGetConcatenate()`
74d092c84bSBrandon Whitchurch @*/
759371c9d4SSatish Balay PetscErrorCode PetscSpaceSumSetConcatenate(PetscSpace sp, PetscBool concatenate) {
76d092c84bSBrandon Whitchurch   PetscFunctionBegin;
77d092c84bSBrandon Whitchurch   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
78cac4c232SBarry Smith   PetscTryMethod(sp, "PetscSpaceSumSetConcatenate_C", (PetscSpace, PetscBool), (sp, concatenate));
79d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
80d092c84bSBrandon Whitchurch }
81d092c84bSBrandon Whitchurch 
82d092c84bSBrandon Whitchurch /*@
83d092c84bSBrandon Whitchurch   PetscSpaceSumGetSubspace - Get a space in the sum
84d092c84bSBrandon Whitchurch 
85d092c84bSBrandon Whitchurch   Input Parameters:
86d092c84bSBrandon Whitchurch + sp - the function space object
87d092c84bSBrandon Whitchurch - s  - The space number
88d092c84bSBrandon Whitchurch 
89d092c84bSBrandon Whitchurch   Output Parameter:
90d092c84bSBrandon Whitchurch . subsp - the PetscSpace
91d092c84bSBrandon Whitchurch 
92d092c84bSBrandon Whitchurch Level: intermediate
93d092c84bSBrandon Whitchurch 
94db781477SPatrick Sanan .seealso: `PetscSpaceSumSetSubspace()`, `PetscSpaceSetDegree()`, `PetscSpaceSetNumVariables()`
95d092c84bSBrandon Whitchurch @*/
969371c9d4SSatish Balay PetscErrorCode PetscSpaceSumGetSubspace(PetscSpace sp, PetscInt s, PetscSpace *subsp) {
97d092c84bSBrandon Whitchurch   PetscFunctionBegin;
98d092c84bSBrandon Whitchurch   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
99d092c84bSBrandon Whitchurch   PetscValidPointer(subsp, 3);
100cac4c232SBarry Smith   PetscTryMethod(sp, "PetscSpaceSumGetSubspace_C", (PetscSpace, PetscInt, PetscSpace *), (sp, s, subsp));
101d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
102d092c84bSBrandon Whitchurch }
103d092c84bSBrandon Whitchurch 
104d092c84bSBrandon Whitchurch /*@
105d092c84bSBrandon Whitchurch   PetscSpaceSumSetSubspace - Set a space in the sum
106d092c84bSBrandon Whitchurch 
107d092c84bSBrandon Whitchurch   Input Parameters:
108d092c84bSBrandon Whitchurch + sp    - the function space object
109d092c84bSBrandon Whitchurch . s     - The space number
110d092c84bSBrandon Whitchurch - subsp - the number of spaces
111d092c84bSBrandon Whitchurch 
112d092c84bSBrandon Whitchurch Level: intermediate
113d092c84bSBrandon Whitchurch 
114db781477SPatrick Sanan .seealso: `PetscSpaceSumGetSubspace()`, `PetscSpaceSetDegree()`, `PetscSpaceSetNumVariables()`
115d092c84bSBrandon Whitchurch @*/
1169371c9d4SSatish Balay PetscErrorCode PetscSpaceSumSetSubspace(PetscSpace sp, PetscInt s, PetscSpace subsp) {
117d092c84bSBrandon Whitchurch   PetscFunctionBegin;
118d092c84bSBrandon Whitchurch   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
119d092c84bSBrandon Whitchurch   if (subsp) PetscValidHeaderSpecific(subsp, PETSCSPACE_CLASSID, 3);
120cac4c232SBarry Smith   PetscTryMethod(sp, "PetscSpaceSumSetSubspace_C", (PetscSpace, PetscInt, PetscSpace), (sp, s, subsp));
121d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
122d092c84bSBrandon Whitchurch }
123d092c84bSBrandon Whitchurch 
1249371c9d4SSatish Balay static PetscErrorCode PetscSpaceSumGetNumSubspaces_Sum(PetscSpace space, PetscInt *numSumSpaces) {
125d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum = (PetscSpace_Sum *)space->data;
126d092c84bSBrandon Whitchurch 
127d092c84bSBrandon Whitchurch   PetscFunctionBegin;
128d092c84bSBrandon Whitchurch   *numSumSpaces = sum->numSumSpaces;
129d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
130d092c84bSBrandon Whitchurch }
131d092c84bSBrandon Whitchurch 
1329371c9d4SSatish Balay static PetscErrorCode PetscSpaceSumSetNumSubspaces_Sum(PetscSpace space, PetscInt numSumSpaces) {
133d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum = (PetscSpace_Sum *)space->data;
134d092c84bSBrandon Whitchurch   PetscInt        Ns  = sum->numSumSpaces;
135d092c84bSBrandon Whitchurch 
136d092c84bSBrandon Whitchurch   PetscFunctionBegin;
13728b400f6SJacob Faibussowitsch   PetscCheck(!sum->setupCalled, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_WRONGSTATE, "Cannot change number of subspaces after setup called");
138d092c84bSBrandon Whitchurch   if (numSumSpaces == Ns) PetscFunctionReturn(0);
139d092c84bSBrandon Whitchurch   if (Ns >= 0) {
140d092c84bSBrandon Whitchurch     PetscInt s;
141*48a46eb9SPierre Jolivet     for (s = 0; s < Ns; ++s) PetscCall(PetscSpaceDestroy(&sum->sumspaces[s]));
1429566063dSJacob Faibussowitsch     PetscCall(PetscFree(sum->sumspaces));
143d092c84bSBrandon Whitchurch   }
144d092c84bSBrandon Whitchurch 
145d092c84bSBrandon Whitchurch   Ns = sum->numSumSpaces = numSumSpaces;
1469566063dSJacob Faibussowitsch   PetscCall(PetscCalloc1(Ns, &sum->sumspaces));
147d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
148d092c84bSBrandon Whitchurch }
149d092c84bSBrandon Whitchurch 
1509371c9d4SSatish Balay static PetscErrorCode PetscSpaceSumGetConcatenate_Sum(PetscSpace sp, PetscBool *concatenate) {
151d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data;
152d092c84bSBrandon Whitchurch 
153d092c84bSBrandon Whitchurch   PetscFunctionBegin;
154d092c84bSBrandon Whitchurch   *concatenate = sum->concatenate;
155d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
156d092c84bSBrandon Whitchurch }
157d092c84bSBrandon Whitchurch 
1589371c9d4SSatish Balay static PetscErrorCode PetscSpaceSumSetConcatenate_Sum(PetscSpace sp, PetscBool concatenate) {
159d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data;
160d092c84bSBrandon Whitchurch 
161d092c84bSBrandon Whitchurch   PetscFunctionBegin;
16228b400f6SJacob Faibussowitsch   PetscCheck(!sum->setupCalled, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_WRONGSTATE, "Cannot change space concatenation after setup called.");
163d092c84bSBrandon Whitchurch 
164d092c84bSBrandon Whitchurch   sum->concatenate = concatenate;
165d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
166d092c84bSBrandon Whitchurch }
167d092c84bSBrandon Whitchurch 
1689371c9d4SSatish Balay static PetscErrorCode PetscSpaceSumGetSubspace_Sum(PetscSpace space, PetscInt s, PetscSpace *subspace) {
169d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum = (PetscSpace_Sum *)space->data;
170d092c84bSBrandon Whitchurch   PetscInt        Ns  = sum->numSumSpaces;
171d092c84bSBrandon Whitchurch 
172d092c84bSBrandon Whitchurch   PetscFunctionBegin;
17308401ef6SPierre Jolivet   PetscCheck(Ns >= 0, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_WRONGSTATE, "Must call PetscSpaceSumSetNumSubspaces() first");
1741dca8a05SBarry Smith   PetscCheck(s >= 0 && s < Ns, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_OUTOFRANGE, "Invalid subspace number %" PetscInt_FMT, s);
175d092c84bSBrandon Whitchurch 
176d092c84bSBrandon Whitchurch   *subspace = sum->sumspaces[s];
177d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
178d092c84bSBrandon Whitchurch }
179d092c84bSBrandon Whitchurch 
1809371c9d4SSatish Balay static PetscErrorCode PetscSpaceSumSetSubspace_Sum(PetscSpace space, PetscInt s, PetscSpace subspace) {
181d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum = (PetscSpace_Sum *)space->data;
182d092c84bSBrandon Whitchurch   PetscInt        Ns  = sum->numSumSpaces;
183d092c84bSBrandon Whitchurch 
184d092c84bSBrandon Whitchurch   PetscFunctionBegin;
18528b400f6SJacob Faibussowitsch   PetscCheck(!sum->setupCalled, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_WRONGSTATE, "Cannot change subspace after setup called");
18608401ef6SPierre Jolivet   PetscCheck(Ns >= 0, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_WRONGSTATE, "Must call PetscSpaceSumSetNumSubspaces() first");
1871dca8a05SBarry Smith   PetscCheck(s >= 0 && s < Ns, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_OUTOFRANGE, "Invalid subspace number %" PetscInt_FMT, s);
188d092c84bSBrandon Whitchurch 
1899566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)subspace));
1909566063dSJacob Faibussowitsch   PetscCall(PetscSpaceDestroy(&sum->sumspaces[s]));
191d092c84bSBrandon Whitchurch   sum->sumspaces[s] = subspace;
192d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
193d092c84bSBrandon Whitchurch }
194d092c84bSBrandon Whitchurch 
1959371c9d4SSatish Balay static PetscErrorCode PetscSpaceSetFromOptions_Sum(PetscSpace sp, PetscOptionItems *PetscOptionsObject) {
196d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data;
197d092c84bSBrandon Whitchurch   PetscInt        Ns, Nc, Nv, deg, i;
198d092c84bSBrandon Whitchurch   PetscBool       concatenate = PETSC_TRUE;
199d092c84bSBrandon Whitchurch   const char     *prefix;
200d092c84bSBrandon Whitchurch 
201d092c84bSBrandon Whitchurch   PetscFunctionBegin;
2029566063dSJacob Faibussowitsch   PetscCall(PetscSpaceGetNumVariables(sp, &Nv));
203d092c84bSBrandon Whitchurch   if (!Nv) PetscFunctionReturn(0);
2049566063dSJacob Faibussowitsch   PetscCall(PetscSpaceGetNumComponents(sp, &Nc));
2059566063dSJacob Faibussowitsch   PetscCall(PetscSpaceSumGetNumSubspaces(sp, &Ns));
2069566063dSJacob Faibussowitsch   PetscCall(PetscSpaceGetDegree(sp, &deg, NULL));
207d092c84bSBrandon Whitchurch   Ns = (Ns == PETSC_DEFAULT) ? 1 : Ns;
208d092c84bSBrandon Whitchurch 
209d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "PetscSpace sum options");
2109566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-petscspace_sum_spaces", "The number of subspaces", "PetscSpaceSumSetNumSubspaces", Ns, &Ns, NULL, 0));
2119371c9d4SSatish Balay   PetscCall(PetscOptionsBool("-petscspace_sum_concatenate", "Subspaces are concatenated components of the final space", "PetscSpaceSumSetFromOptions", concatenate, &concatenate, NULL));
212d0609cedSBarry Smith   PetscOptionsHeadEnd();
213d092c84bSBrandon Whitchurch 
2141dca8a05SBarry Smith   PetscCheck(Ns >= 0 && (Nv <= 0 || Ns != 0), PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_OUTOFRANGE, "Cannot have a sum space of %" PetscInt_FMT " spaces", Ns);
215*48a46eb9SPierre Jolivet   if (Ns != sum->numSumSpaces) PetscCall(PetscSpaceSumSetNumSubspaces(sp, Ns));
2169566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)sp, &prefix));
217d092c84bSBrandon Whitchurch   for (i = 0; i < Ns; ++i) {
218d092c84bSBrandon Whitchurch     PetscInt   sNv;
219d092c84bSBrandon Whitchurch     PetscSpace subspace;
220d092c84bSBrandon Whitchurch 
2219566063dSJacob Faibussowitsch     PetscCall(PetscSpaceSumGetSubspace(sp, i, &subspace));
222d092c84bSBrandon Whitchurch     if (!subspace) {
223d092c84bSBrandon Whitchurch       char subspacePrefix[256];
224d092c84bSBrandon Whitchurch 
2259566063dSJacob Faibussowitsch       PetscCall(PetscSpaceCreate(PetscObjectComm((PetscObject)sp), &subspace));
2269566063dSJacob Faibussowitsch       PetscCall(PetscObjectSetOptionsPrefix((PetscObject)subspace, prefix));
22763a3b9bcSJacob Faibussowitsch       PetscCall(PetscSNPrintf(subspacePrefix, 256, "sumcomp_%" PetscInt_FMT "_", i));
2289566063dSJacob Faibussowitsch       PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)subspace, subspacePrefix));
2291baa6e33SBarry Smith     } else PetscCall(PetscObjectReference((PetscObject)subspace));
2309566063dSJacob Faibussowitsch     PetscCall(PetscSpaceSetFromOptions(subspace));
2319566063dSJacob Faibussowitsch     PetscCall(PetscSpaceGetNumVariables(subspace, &sNv));
23263a3b9bcSJacob Faibussowitsch     PetscCheck(sNv, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_WRONGSTATE, "Subspace %" PetscInt_FMT " has not been set properly, number of variables is 0.", i);
2339566063dSJacob Faibussowitsch     PetscCall(PetscSpaceSumSetSubspace(sp, i, subspace));
2349566063dSJacob Faibussowitsch     PetscCall(PetscSpaceDestroy(&subspace));
235d092c84bSBrandon Whitchurch   }
236d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
237d092c84bSBrandon Whitchurch }
238d092c84bSBrandon Whitchurch 
2399371c9d4SSatish Balay static PetscErrorCode PetscSpaceSetUp_Sum(PetscSpace sp) {
240d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum         = (PetscSpace_Sum *)sp->data;
241d092c84bSBrandon Whitchurch   PetscBool       concatenate = PETSC_TRUE;
242642c7897SToby Isaac   PetscBool       uniform;
243642c7897SToby Isaac   PetscInt        Nv, Ns, Nc, i, sum_Nc = 0, deg = PETSC_MAX_INT, maxDeg = PETSC_MIN_INT;
244642c7897SToby Isaac   PetscInt        minNc, maxNc;
245d092c84bSBrandon Whitchurch 
246d092c84bSBrandon Whitchurch   PetscFunctionBegin;
247d092c84bSBrandon Whitchurch   if (sum->setupCalled) PetscFunctionReturn(0);
248d092c84bSBrandon Whitchurch 
2499566063dSJacob Faibussowitsch   PetscCall(PetscSpaceGetNumVariables(sp, &Nv));
2509566063dSJacob Faibussowitsch   PetscCall(PetscSpaceGetNumComponents(sp, &Nc));
2519566063dSJacob Faibussowitsch   PetscCall(PetscSpaceSumGetNumSubspaces(sp, &Ns));
252d092c84bSBrandon Whitchurch   if (Ns == PETSC_DEFAULT) {
253d092c84bSBrandon Whitchurch     Ns = 1;
2549566063dSJacob Faibussowitsch     PetscCall(PetscSpaceSumSetNumSubspaces(sp, Ns));
255d092c84bSBrandon Whitchurch   }
25663a3b9bcSJacob Faibussowitsch   PetscCheck(Ns >= 0, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_OUTOFRANGE, "Cannot have %" PetscInt_FMT " subspaces", Ns);
257642c7897SToby Isaac   uniform = PETSC_TRUE;
258642c7897SToby Isaac   if (Ns) {
259642c7897SToby Isaac     PetscSpace s0;
260d092c84bSBrandon Whitchurch 
2619566063dSJacob Faibussowitsch     PetscCall(PetscSpaceSumGetSubspace(sp, 0, &s0));
262642c7897SToby Isaac     for (PetscInt i = 1; i < Ns; i++) {
263642c7897SToby Isaac       PetscSpace si;
264642c7897SToby Isaac 
2659566063dSJacob Faibussowitsch       PetscCall(PetscSpaceSumGetSubspace(sp, i, &si));
266642c7897SToby Isaac       if (si != s0) {
267642c7897SToby Isaac         uniform = PETSC_FALSE;
268642c7897SToby Isaac         break;
269642c7897SToby Isaac       }
270642c7897SToby Isaac     }
271642c7897SToby Isaac   }
272642c7897SToby Isaac 
273642c7897SToby Isaac   minNc = Nc;
274642c7897SToby Isaac   maxNc = Nc;
275d092c84bSBrandon Whitchurch   for (i = 0; i < Ns; ++i) {
276d092c84bSBrandon Whitchurch     PetscInt   sNv, sNc, iDeg, iMaxDeg;
277d092c84bSBrandon Whitchurch     PetscSpace si;
278d092c84bSBrandon Whitchurch 
2799566063dSJacob Faibussowitsch     PetscCall(PetscSpaceSumGetSubspace(sp, i, &si));
2809566063dSJacob Faibussowitsch     PetscCall(PetscSpaceSetUp(si));
2819566063dSJacob Faibussowitsch     PetscCall(PetscSpaceGetNumVariables(si, &sNv));
28263a3b9bcSJacob Faibussowitsch     PetscCheck(sNv == Nv, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_WRONGSTATE, "Subspace %" PetscInt_FMT " has %" PetscInt_FMT " variables, space has %" PetscInt_FMT ".", i, sNv, Nv);
2839566063dSJacob Faibussowitsch     PetscCall(PetscSpaceGetNumComponents(si, &sNc));
284d092c84bSBrandon Whitchurch     if (i == 0 && sNc == Nc) concatenate = PETSC_FALSE;
285642c7897SToby Isaac     minNc = PetscMin(minNc, sNc);
286642c7897SToby Isaac     maxNc = PetscMax(maxNc, sNc);
287d092c84bSBrandon Whitchurch     sum_Nc += sNc;
2889566063dSJacob Faibussowitsch     PetscCall(PetscSpaceSumGetSubspace(sp, i, &si));
2899566063dSJacob Faibussowitsch     PetscCall(PetscSpaceGetDegree(si, &iDeg, &iMaxDeg));
290642c7897SToby Isaac     deg    = PetscMin(deg, iDeg);
291d092c84bSBrandon Whitchurch     maxDeg = PetscMax(maxDeg, iMaxDeg);
292d092c84bSBrandon Whitchurch   }
293d092c84bSBrandon Whitchurch 
2947a46b595SBarry Smith   if (concatenate) PetscCheck(sum_Nc == Nc, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_OUTOFRANGE, "Total number of subspace components (%" PetscInt_FMT ") does not match number of target space components (%" PetscInt_FMT ").", sum_Nc, Nc);
2957a46b595SBarry Smith   else PetscCheck(minNc == Nc && maxNc == Nc, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_OUTOFRANGE, "Subspaces must have same number of components as the target space.");
296d092c84bSBrandon Whitchurch 
297d092c84bSBrandon Whitchurch   sp->degree       = deg;
298d092c84bSBrandon Whitchurch   sp->maxDegree    = maxDeg;
299d092c84bSBrandon Whitchurch   sum->concatenate = concatenate;
300642c7897SToby Isaac   sum->uniform     = uniform;
301d092c84bSBrandon Whitchurch   sum->setupCalled = PETSC_TRUE;
302d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
303d092c84bSBrandon Whitchurch }
304d092c84bSBrandon Whitchurch 
3059371c9d4SSatish Balay static PetscErrorCode PetscSpaceSumView_Ascii(PetscSpace sp, PetscViewer v) {
306d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum         = (PetscSpace_Sum *)sp->data;
307d092c84bSBrandon Whitchurch   PetscBool       concatenate = sum->concatenate;
308d092c84bSBrandon Whitchurch   PetscInt        i, Ns = sum->numSumSpaces;
309d092c84bSBrandon Whitchurch 
310d092c84bSBrandon Whitchurch   PetscFunctionBegin;
3111baa6e33SBarry Smith   if (concatenate) PetscCall(PetscViewerASCIIPrintf(v, "Sum space of %" PetscInt_FMT " concatenated subspaces%s\n", Ns, sum->uniform ? " (all identical)" : ""));
3121baa6e33SBarry Smith   else PetscCall(PetscViewerASCIIPrintf(v, "Sum space of %" PetscInt_FMT " subspaces%s\n", Ns, sum->uniform ? " (all identical)" : ""));
313642c7897SToby Isaac   for (i = 0; i < (sum->uniform ? (Ns > 0 ? 1 : 0) : Ns); ++i) {
3149566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(v));
3159566063dSJacob Faibussowitsch     PetscCall(PetscSpaceView(sum->sumspaces[i], v));
3169566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(v));
317d092c84bSBrandon Whitchurch   }
318d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
319d092c84bSBrandon Whitchurch }
320d092c84bSBrandon Whitchurch 
3219371c9d4SSatish Balay static PetscErrorCode PetscSpaceView_Sum(PetscSpace sp, PetscViewer viewer) {
322d092c84bSBrandon Whitchurch   PetscBool iascii;
323d092c84bSBrandon Whitchurch 
324d092c84bSBrandon Whitchurch   PetscFunctionBegin;
3259566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
3261baa6e33SBarry Smith   if (iascii) PetscCall(PetscSpaceSumView_Ascii(sp, viewer));
327d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
328d092c84bSBrandon Whitchurch }
329d092c84bSBrandon Whitchurch 
3309371c9d4SSatish Balay static PetscErrorCode PetscSpaceDestroy_Sum(PetscSpace sp) {
331d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data;
332d092c84bSBrandon Whitchurch   PetscInt        i, Ns = sum->numSumSpaces;
333d092c84bSBrandon Whitchurch 
334d092c84bSBrandon Whitchurch   PetscFunctionBegin;
335*48a46eb9SPierre Jolivet   for (i = 0; i < Ns; ++i) PetscCall(PetscSpaceDestroy(&sum->sumspaces[i]));
3369566063dSJacob Faibussowitsch   PetscCall(PetscFree(sum->sumspaces));
337642c7897SToby Isaac   if (sum->heightsubspaces) {
338642c7897SToby Isaac     PetscInt d;
339642c7897SToby Isaac 
340642c7897SToby Isaac     /* sp->Nv is the spatial dimension, so it is equal to the number
341642c7897SToby Isaac      * of subspaces on higher co-dimension points */
342*48a46eb9SPierre Jolivet     for (d = 0; d < sp->Nv; ++d) PetscCall(PetscSpaceDestroy(&sum->heightsubspaces[d]));
343642c7897SToby Isaac   }
3449566063dSJacob Faibussowitsch   PetscCall(PetscFree(sum->heightsubspaces));
3459566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetSubspace_C", NULL));
3469566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetSubspace_C", NULL));
3479566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetNumSubspaces_C", NULL));
3489566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetNumSubspaces_C", NULL));
3492e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetConcatenate_C", NULL));
3502e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetConcatenate_C", NULL));
3519566063dSJacob Faibussowitsch   PetscCall(PetscFree(sum));
352d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
353d092c84bSBrandon Whitchurch }
354d092c84bSBrandon Whitchurch 
3559371c9d4SSatish Balay static PetscErrorCode PetscSpaceGetDimension_Sum(PetscSpace sp, PetscInt *dim) {
356d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data;
357d092c84bSBrandon Whitchurch   PetscInt        i, d = 0, Ns = sum->numSumSpaces;
358d092c84bSBrandon Whitchurch 
359d092c84bSBrandon Whitchurch   PetscFunctionBegin;
360642c7897SToby Isaac   if (!sum->setupCalled) {
3619566063dSJacob Faibussowitsch     PetscCall(PetscSpaceSetUp(sp));
3629566063dSJacob Faibussowitsch     PetscCall(PetscSpaceGetDimension(sp, dim));
363642c7897SToby Isaac     PetscFunctionReturn(0);
364642c7897SToby Isaac   }
365d092c84bSBrandon Whitchurch 
366d092c84bSBrandon Whitchurch   for (i = 0; i < Ns; ++i) {
367d092c84bSBrandon Whitchurch     PetscInt id;
368d092c84bSBrandon Whitchurch 
3699566063dSJacob Faibussowitsch     PetscCall(PetscSpaceGetDimension(sum->sumspaces[i], &id));
370d092c84bSBrandon Whitchurch     d += id;
371d092c84bSBrandon Whitchurch   }
372d092c84bSBrandon Whitchurch 
373d092c84bSBrandon Whitchurch   *dim = d;
374d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
375d092c84bSBrandon Whitchurch }
376d092c84bSBrandon Whitchurch 
3779371c9d4SSatish Balay static PetscErrorCode PetscSpaceEvaluate_Sum(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[]) {
378d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum         = (PetscSpace_Sum *)sp->data;
379d092c84bSBrandon Whitchurch   PetscBool       concatenate = sum->concatenate;
380d092c84bSBrandon Whitchurch   DM              dm          = sp->dm;
381d092c84bSBrandon Whitchurch   PetscInt        Nc = sp->Nc, Nv = sp->Nv, Ns = sum->numSumSpaces;
382d092c84bSBrandon Whitchurch   PetscInt        i, s, offset, ncoffset, pdimfull, numelB, numelD, numelH;
383d092c84bSBrandon Whitchurch   PetscReal      *sB = NULL, *sD = NULL, *sH = NULL;
384d092c84bSBrandon Whitchurch 
385d092c84bSBrandon Whitchurch   PetscFunctionBegin;
386d092c84bSBrandon Whitchurch   if (!sum->setupCalled) {
3879566063dSJacob Faibussowitsch     PetscCall(PetscSpaceSetUp(sp));
3889566063dSJacob Faibussowitsch     PetscCall(PetscSpaceEvaluate(sp, npoints, points, B, D, H));
389642c7897SToby Isaac     PetscFunctionReturn(0);
390d092c84bSBrandon Whitchurch   }
3919566063dSJacob Faibussowitsch   PetscCall(PetscSpaceGetDimension(sp, &pdimfull));
392d092c84bSBrandon Whitchurch   numelB = npoints * pdimfull * Nc;
393d092c84bSBrandon Whitchurch   numelD = numelB * Nv;
394d092c84bSBrandon Whitchurch   numelH = numelD * Nv;
395*48a46eb9SPierre Jolivet   if (B || D || H) PetscCall(DMGetWorkArray(dm, numelB, MPIU_REAL, &sB));
396*48a46eb9SPierre Jolivet   if (D || H) PetscCall(DMGetWorkArray(dm, numelD, MPIU_REAL, &sD));
397*48a46eb9SPierre Jolivet   if (H) PetscCall(DMGetWorkArray(dm, numelH, MPIU_REAL, &sH));
398d092c84bSBrandon Whitchurch   if (B)
399d092c84bSBrandon Whitchurch     for (i = 0; i < numelB; ++i) B[i] = 0.;
400d092c84bSBrandon Whitchurch   if (D)
401d092c84bSBrandon Whitchurch     for (i = 0; i < numelD; ++i) D[i] = 0.;
402d092c84bSBrandon Whitchurch   if (H)
403d092c84bSBrandon Whitchurch     for (i = 0; i < numelH; ++i) H[i] = 0.;
404d092c84bSBrandon Whitchurch 
405d092c84bSBrandon Whitchurch   for (s = 0, offset = 0, ncoffset = 0; s < Ns; ++s) {
406d092c84bSBrandon Whitchurch     PetscInt sNv, spdim, sNc, p;
407d092c84bSBrandon Whitchurch 
4089566063dSJacob Faibussowitsch     PetscCall(PetscSpaceGetNumVariables(sum->sumspaces[s], &sNv));
4099566063dSJacob Faibussowitsch     PetscCall(PetscSpaceGetNumComponents(sum->sumspaces[s], &sNc));
4109566063dSJacob Faibussowitsch     PetscCall(PetscSpaceGetDimension(sum->sumspaces[s], &spdim));
4111dca8a05SBarry Smith     PetscCheck(offset + spdim <= pdimfull, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_OUTOFRANGE, "Subspace dimensions exceed target space dimension.");
412*48a46eb9SPierre Jolivet     if (s == 0 || !sum->uniform) PetscCall(PetscSpaceEvaluate(sum->sumspaces[s], npoints, points, sB, sD, sH));
413d092c84bSBrandon Whitchurch     if (B || D || H) {
414d092c84bSBrandon Whitchurch       for (p = 0; p < npoints; ++p) {
415d092c84bSBrandon Whitchurch         PetscInt j;
416d092c84bSBrandon Whitchurch 
417d092c84bSBrandon Whitchurch         for (j = 0; j < spdim; ++j) {
418d092c84bSBrandon Whitchurch           PetscInt c;
419d092c84bSBrandon Whitchurch 
420d092c84bSBrandon Whitchurch           for (c = 0; c < sNc; ++c) {
421d092c84bSBrandon Whitchurch             PetscInt compoffset, BInd, sBInd;
422d092c84bSBrandon Whitchurch 
423d092c84bSBrandon Whitchurch             compoffset = concatenate ? c + ncoffset : c;
424d092c84bSBrandon Whitchurch             BInd       = (p * pdimfull + j + offset) * Nc + compoffset;
425d092c84bSBrandon Whitchurch             sBInd      = (p * spdim + j) * sNc + c;
426642c7897SToby Isaac             if (B) B[BInd] = sB[sBInd];
427d092c84bSBrandon Whitchurch             if (D || H) {
428d092c84bSBrandon Whitchurch               PetscInt v;
429d092c84bSBrandon Whitchurch 
430d092c84bSBrandon Whitchurch               for (v = 0; v < Nv; ++v) {
431d092c84bSBrandon Whitchurch                 PetscInt DInd, sDInd;
432d092c84bSBrandon Whitchurch 
433d092c84bSBrandon Whitchurch                 DInd  = BInd * Nv + v;
434d092c84bSBrandon Whitchurch                 sDInd = sBInd * Nv + v;
435642c7897SToby Isaac                 if (D) D[DInd] = sD[sDInd];
436d092c84bSBrandon Whitchurch                 if (H) {
437d092c84bSBrandon Whitchurch                   PetscInt v2;
438d092c84bSBrandon Whitchurch 
439d092c84bSBrandon Whitchurch                   for (v2 = 0; v2 < Nv; ++v2) {
440d092c84bSBrandon Whitchurch                     PetscInt HInd, sHInd;
441d092c84bSBrandon Whitchurch 
442d092c84bSBrandon Whitchurch                     HInd    = DInd * Nv + v2;
443d092c84bSBrandon Whitchurch                     sHInd   = sDInd * Nv + v2;
444642c7897SToby Isaac                     H[HInd] = sH[sHInd];
445d092c84bSBrandon Whitchurch                   }
446d092c84bSBrandon Whitchurch                 }
447d092c84bSBrandon Whitchurch               }
448d092c84bSBrandon Whitchurch             }
449d092c84bSBrandon Whitchurch           }
450d092c84bSBrandon Whitchurch         }
451d092c84bSBrandon Whitchurch       }
452d092c84bSBrandon Whitchurch     }
453d092c84bSBrandon Whitchurch     offset += spdim;
454d092c84bSBrandon Whitchurch     ncoffset += sNc;
455d092c84bSBrandon Whitchurch   }
456d092c84bSBrandon Whitchurch 
457*48a46eb9SPierre Jolivet   if (H) PetscCall(DMRestoreWorkArray(dm, numelH, MPIU_REAL, &sH));
458*48a46eb9SPierre Jolivet   if (D || H) PetscCall(DMRestoreWorkArray(dm, numelD, MPIU_REAL, &sD));
459*48a46eb9SPierre Jolivet   if (B || D || H) PetscCall(DMRestoreWorkArray(dm, numelB, MPIU_REAL, &sB));
460d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
461d092c84bSBrandon Whitchurch }
462d092c84bSBrandon Whitchurch 
4639371c9d4SSatish Balay static PetscErrorCode PetscSpaceGetHeightSubspace_Sum(PetscSpace sp, PetscInt height, PetscSpace *subsp) {
464642c7897SToby Isaac   PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data;
465642c7897SToby Isaac   PetscInt        Nc, dim, order;
466642c7897SToby Isaac   PetscBool       tensor;
467642c7897SToby Isaac 
468642c7897SToby Isaac   PetscFunctionBegin;
4699566063dSJacob Faibussowitsch   PetscCall(PetscSpaceGetNumComponents(sp, &Nc));
4709566063dSJacob Faibussowitsch   PetscCall(PetscSpaceGetNumVariables(sp, &dim));
4719566063dSJacob Faibussowitsch   PetscCall(PetscSpaceGetDegree(sp, &order, NULL));
4729566063dSJacob Faibussowitsch   PetscCall(PetscSpacePolynomialGetTensor(sp, &tensor));
4731dca8a05SBarry 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);
4749566063dSJacob Faibussowitsch   if (!sum->heightsubspaces) PetscCall(PetscCalloc1(dim, &sum->heightsubspaces));
475642c7897SToby Isaac   if (height <= dim) {
476642c7897SToby Isaac     if (!sum->heightsubspaces[height - 1]) {
477642c7897SToby Isaac       PetscSpace  sub;
478642c7897SToby Isaac       const char *name;
479642c7897SToby Isaac 
4809566063dSJacob Faibussowitsch       PetscCall(PetscSpaceCreate(PetscObjectComm((PetscObject)sp), &sub));
4819566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetName((PetscObject)sp, &name));
4829566063dSJacob Faibussowitsch       PetscCall(PetscObjectSetName((PetscObject)sub, name));
4839566063dSJacob Faibussowitsch       PetscCall(PetscSpaceSetType(sub, PETSCSPACESUM));
4849566063dSJacob Faibussowitsch       PetscCall(PetscSpaceSumSetNumSubspaces(sub, sum->numSumSpaces));
4859566063dSJacob Faibussowitsch       PetscCall(PetscSpaceSumSetConcatenate(sub, sum->concatenate));
4869566063dSJacob Faibussowitsch       PetscCall(PetscSpaceSetNumComponents(sub, Nc));
4879566063dSJacob Faibussowitsch       PetscCall(PetscSpaceSetNumVariables(sub, dim - height));
488642c7897SToby Isaac       for (PetscInt i = 0; i < sum->numSumSpaces; i++) {
489642c7897SToby Isaac         PetscSpace subh;
490642c7897SToby Isaac 
4919566063dSJacob Faibussowitsch         PetscCall(PetscSpaceGetHeightSubspace(sum->sumspaces[i], height, &subh));
4929566063dSJacob Faibussowitsch         PetscCall(PetscSpaceSumSetSubspace(sub, i, subh));
493642c7897SToby Isaac       }
4949566063dSJacob Faibussowitsch       PetscCall(PetscSpaceSetUp(sub));
495642c7897SToby Isaac       sum->heightsubspaces[height - 1] = sub;
496642c7897SToby Isaac     }
497642c7897SToby Isaac     *subsp = sum->heightsubspaces[height - 1];
498642c7897SToby Isaac   } else {
499642c7897SToby Isaac     *subsp = NULL;
500642c7897SToby Isaac   }
501642c7897SToby Isaac   PetscFunctionReturn(0);
502642c7897SToby Isaac }
503642c7897SToby Isaac 
5049371c9d4SSatish Balay static PetscErrorCode PetscSpaceInitialize_Sum(PetscSpace sp) {
505d092c84bSBrandon Whitchurch   PetscFunctionBegin;
506d092c84bSBrandon Whitchurch   sp->ops->setfromoptions    = PetscSpaceSetFromOptions_Sum;
507d092c84bSBrandon Whitchurch   sp->ops->setup             = PetscSpaceSetUp_Sum;
508d092c84bSBrandon Whitchurch   sp->ops->view              = PetscSpaceView_Sum;
509d092c84bSBrandon Whitchurch   sp->ops->destroy           = PetscSpaceDestroy_Sum;
510d092c84bSBrandon Whitchurch   sp->ops->getdimension      = PetscSpaceGetDimension_Sum;
511d092c84bSBrandon Whitchurch   sp->ops->evaluate          = PetscSpaceEvaluate_Sum;
512642c7897SToby Isaac   sp->ops->getheightsubspace = PetscSpaceGetHeightSubspace_Sum;
513d092c84bSBrandon Whitchurch 
5149566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetNumSubspaces_C", PetscSpaceSumGetNumSubspaces_Sum));
5159566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetNumSubspaces_C", PetscSpaceSumSetNumSubspaces_Sum));
5169566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetSubspace_C", PetscSpaceSumGetSubspace_Sum));
5179566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetSubspace_C", PetscSpaceSumSetSubspace_Sum));
5189566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetConcatenate_C", PetscSpaceSumGetConcatenate_Sum));
5199566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetConcatenate_C", PetscSpaceSumSetConcatenate_Sum));
520d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
521d092c84bSBrandon Whitchurch }
522d092c84bSBrandon Whitchurch 
523d092c84bSBrandon Whitchurch /*MC
524d092c84bSBrandon Whitchurch   PETSCSPACESUM = "sum" - A PetscSpace object that encapsulates a sum of subspaces.
525d092c84bSBrandon Whitchurch   That sum can either be direct or concatenate a concatenation.For example if A and B are spaces each with 2 components,
526d092c84bSBrandon 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
527d092c84bSBrandon Whitchurch   same number of variables.
528d092c84bSBrandon Whitchurch 
529d092c84bSBrandon Whitchurch Level: intermediate
530d092c84bSBrandon Whitchurch 
531db781477SPatrick Sanan .seealso: `PetscSpaceType`, `PetscSpaceCreate()`, `PetscSpaceSetType()`
532d092c84bSBrandon Whitchurch M*/
5339371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscSpaceCreate_Sum(PetscSpace sp) {
534d092c84bSBrandon Whitchurch   PetscSpace_Sum *sum;
535d092c84bSBrandon Whitchurch 
536d092c84bSBrandon Whitchurch   PetscFunctionBegin;
537d092c84bSBrandon Whitchurch   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
5389566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(sp, &sum));
539642c7897SToby Isaac   sum->numSumSpaces = PETSC_DEFAULT;
540d092c84bSBrandon Whitchurch   sp->data          = sum;
5419566063dSJacob Faibussowitsch   PetscCall(PetscSpaceInitialize_Sum(sp));
542d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
543d092c84bSBrandon Whitchurch }
544d092c84bSBrandon Whitchurch 
5459371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscSpaceCreateSum(PetscInt numSubspaces, const PetscSpace subspaces[], PetscBool concatenate, PetscSpace *sumSpace) {
546d092c84bSBrandon Whitchurch   PetscInt i, Nv, Nc = 0;
547d092c84bSBrandon Whitchurch 
548d092c84bSBrandon Whitchurch   PetscFunctionBegin;
5491baa6e33SBarry Smith   if (sumSpace) PetscCall(PetscSpaceDestroy(sumSpace));
5509566063dSJacob Faibussowitsch   PetscCall(PetscSpaceCreate(PetscObjectComm((PetscObject)subspaces[0]), sumSpace));
5519566063dSJacob Faibussowitsch   PetscCall(PetscSpaceSetType(*sumSpace, PETSCSPACESUM));
5529566063dSJacob Faibussowitsch   PetscCall(PetscSpaceSumSetNumSubspaces(*sumSpace, numSubspaces));
5539566063dSJacob Faibussowitsch   PetscCall(PetscSpaceSumSetConcatenate(*sumSpace, concatenate));
554d092c84bSBrandon Whitchurch   for (i = 0; i < numSubspaces; ++i) {
555d092c84bSBrandon Whitchurch     PetscInt sNc;
556d092c84bSBrandon Whitchurch 
5579566063dSJacob Faibussowitsch     PetscCall(PetscSpaceSumSetSubspace(*sumSpace, i, subspaces[i]));
5589566063dSJacob Faibussowitsch     PetscCall(PetscSpaceGetNumComponents(subspaces[i], &sNc));
559d092c84bSBrandon Whitchurch     if (concatenate) Nc += sNc;
560d092c84bSBrandon Whitchurch     else Nc = sNc;
561d092c84bSBrandon Whitchurch   }
5629566063dSJacob Faibussowitsch   PetscCall(PetscSpaceGetNumVariables(subspaces[0], &Nv));
5639566063dSJacob Faibussowitsch   PetscCall(PetscSpaceSetNumComponents(*sumSpace, Nc));
5649566063dSJacob Faibussowitsch   PetscCall(PetscSpaceSetNumVariables(*sumSpace, Nv));
5659566063dSJacob Faibussowitsch   PetscCall(PetscSpaceSetUp(*sumSpace));
566d092c84bSBrandon Whitchurch 
567d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
568d092c84bSBrandon Whitchurch }
569