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, °, 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