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 13*dce8aebaSBarry Smith .seealso: `PETSCSPACESUM`, `PetscSpace`, `PetscSpaceSumSetNumSubspaces()`, `PetscSpaceSetDegree()`, `PetscSpaceSetNumVariables()` 14d092c84bSBrandon Whitchurch @*/ 15d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSpaceSumGetNumSubspaces(PetscSpace sp, PetscInt *numSumSpaces) 16d71ae5a4SJacob Faibussowitsch { 17d092c84bSBrandon Whitchurch PetscFunctionBegin; 18d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 19d092c84bSBrandon Whitchurch PetscValidIntPointer(numSumSpaces, 2); 20cac4c232SBarry Smith 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 33*dce8aebaSBarry Smith .seealso: `PETSCSPACESUM`, `PetscSpace`, `PetscSpaceSumGetNumSubspaces()`, `PetscSpaceSetDegree()`, `PetscSpaceSetNumVariables()` 34d092c84bSBrandon Whitchurch @*/ 35d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSpaceSumSetNumSubspaces(PetscSpace sp, PetscInt numSumSpaces) 36d71ae5a4SJacob Faibussowitsch { 37d092c84bSBrandon Whitchurch PetscFunctionBegin; 38d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 39cac4c232SBarry Smith 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 56*dce8aebaSBarry Smith .seealso: `PETSCSPACESUM`, `PetscSpace`, `PetscSpaceSumSetConcatenate()` 57d092c84bSBrandon Whitchurch @*/ 58d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSpaceSumGetConcatenate(PetscSpace sp, PetscBool *concatenate) 59d71ae5a4SJacob Faibussowitsch { 60d092c84bSBrandon Whitchurch PetscFunctionBegin; 61d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 62cac4c232SBarry Smith 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 76*dce8aebaSBarry Smith 77*dce8aebaSBarry Smith .seealso: `PETSCSPACESUM`, `PetscSpace`, `PetscSpaceSumGetConcatenate()` 78d092c84bSBrandon Whitchurch @*/ 79d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSpaceSumSetConcatenate(PetscSpace sp, PetscBool concatenate) 80d71ae5a4SJacob Faibussowitsch { 81d092c84bSBrandon Whitchurch PetscFunctionBegin; 82d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 83cac4c232SBarry Smith PetscTryMethod(sp, "PetscSpaceSumSetConcatenate_C", (PetscSpace, PetscBool), (sp, concatenate)); 84d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 85d092c84bSBrandon Whitchurch } 86d092c84bSBrandon Whitchurch 87d092c84bSBrandon Whitchurch /*@ 88d092c84bSBrandon Whitchurch PetscSpaceSumGetSubspace - Get a space in the sum 89d092c84bSBrandon Whitchurch 90d092c84bSBrandon Whitchurch Input Parameters: 91d092c84bSBrandon Whitchurch + sp - the function space object 92d092c84bSBrandon Whitchurch - s - The space number 93d092c84bSBrandon Whitchurch 94d092c84bSBrandon Whitchurch Output Parameter: 95d092c84bSBrandon Whitchurch . subsp - the PetscSpace 96d092c84bSBrandon Whitchurch 97d092c84bSBrandon Whitchurch Level: intermediate 98d092c84bSBrandon Whitchurch 99*dce8aebaSBarry Smith .seealso: `PETSCSPACESUM`, `PetscSpace`, `PetscSpaceSumSetSubspace()`, `PetscSpaceSetDegree()`, `PetscSpaceSetNumVariables()` 100d092c84bSBrandon Whitchurch @*/ 101d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSpaceSumGetSubspace(PetscSpace sp, PetscInt s, PetscSpace *subsp) 102d71ae5a4SJacob Faibussowitsch { 103d092c84bSBrandon Whitchurch PetscFunctionBegin; 104d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 105d092c84bSBrandon Whitchurch PetscValidPointer(subsp, 3); 106cac4c232SBarry Smith PetscTryMethod(sp, "PetscSpaceSumGetSubspace_C", (PetscSpace, PetscInt, PetscSpace *), (sp, s, subsp)); 107d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 108d092c84bSBrandon Whitchurch } 109d092c84bSBrandon Whitchurch 110d092c84bSBrandon Whitchurch /*@ 111d092c84bSBrandon Whitchurch PetscSpaceSumSetSubspace - Set a space in the sum 112d092c84bSBrandon Whitchurch 113d092c84bSBrandon Whitchurch Input Parameters: 114d092c84bSBrandon Whitchurch + sp - the function space object 115d092c84bSBrandon Whitchurch . s - The space number 116d092c84bSBrandon Whitchurch - subsp - the number of spaces 117d092c84bSBrandon Whitchurch 118d092c84bSBrandon Whitchurch Level: intermediate 119d092c84bSBrandon Whitchurch 120*dce8aebaSBarry Smith .seealso: `PETSCSPACESUM`, `PetscSpace`, `PetscSpaceSumGetSubspace()`, `PetscSpaceSetDegree()`, `PetscSpaceSetNumVariables()` 121d092c84bSBrandon Whitchurch @*/ 122d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSpaceSumSetSubspace(PetscSpace sp, PetscInt s, PetscSpace subsp) 123d71ae5a4SJacob Faibussowitsch { 124d092c84bSBrandon Whitchurch PetscFunctionBegin; 125d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 126d092c84bSBrandon Whitchurch if (subsp) PetscValidHeaderSpecific(subsp, PETSCSPACE_CLASSID, 3); 127cac4c232SBarry Smith PetscTryMethod(sp, "PetscSpaceSumSetSubspace_C", (PetscSpace, PetscInt, PetscSpace), (sp, s, subsp)); 128d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 129d092c84bSBrandon Whitchurch } 130d092c84bSBrandon Whitchurch 131d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSumGetNumSubspaces_Sum(PetscSpace space, PetscInt *numSumSpaces) 132d71ae5a4SJacob Faibussowitsch { 133d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)space->data; 134d092c84bSBrandon Whitchurch 135d092c84bSBrandon Whitchurch PetscFunctionBegin; 136d092c84bSBrandon Whitchurch *numSumSpaces = sum->numSumSpaces; 137d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 138d092c84bSBrandon Whitchurch } 139d092c84bSBrandon Whitchurch 140d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSumSetNumSubspaces_Sum(PetscSpace space, PetscInt numSumSpaces) 141d71ae5a4SJacob Faibussowitsch { 142d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)space->data; 143d092c84bSBrandon Whitchurch PetscInt Ns = sum->numSumSpaces; 144d092c84bSBrandon Whitchurch 145d092c84bSBrandon Whitchurch PetscFunctionBegin; 14628b400f6SJacob Faibussowitsch PetscCheck(!sum->setupCalled, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_WRONGSTATE, "Cannot change number of subspaces after setup called"); 147d092c84bSBrandon Whitchurch if (numSumSpaces == Ns) PetscFunctionReturn(0); 148d092c84bSBrandon Whitchurch if (Ns >= 0) { 149d092c84bSBrandon Whitchurch PetscInt s; 15048a46eb9SPierre Jolivet for (s = 0; s < Ns; ++s) PetscCall(PetscSpaceDestroy(&sum->sumspaces[s])); 1519566063dSJacob Faibussowitsch PetscCall(PetscFree(sum->sumspaces)); 152d092c84bSBrandon Whitchurch } 153d092c84bSBrandon Whitchurch 154d092c84bSBrandon Whitchurch Ns = sum->numSumSpaces = numSumSpaces; 1559566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Ns, &sum->sumspaces)); 156d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 157d092c84bSBrandon Whitchurch } 158d092c84bSBrandon Whitchurch 159d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSumGetConcatenate_Sum(PetscSpace sp, PetscBool *concatenate) 160d71ae5a4SJacob Faibussowitsch { 161d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 162d092c84bSBrandon Whitchurch 163d092c84bSBrandon Whitchurch PetscFunctionBegin; 164d092c84bSBrandon Whitchurch *concatenate = sum->concatenate; 165d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 166d092c84bSBrandon Whitchurch } 167d092c84bSBrandon Whitchurch 168d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSumSetConcatenate_Sum(PetscSpace sp, PetscBool concatenate) 169d71ae5a4SJacob Faibussowitsch { 170d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 171d092c84bSBrandon Whitchurch 172d092c84bSBrandon Whitchurch PetscFunctionBegin; 17328b400f6SJacob Faibussowitsch PetscCheck(!sum->setupCalled, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_WRONGSTATE, "Cannot change space concatenation after setup called."); 174d092c84bSBrandon Whitchurch 175d092c84bSBrandon Whitchurch sum->concatenate = concatenate; 176d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 177d092c84bSBrandon Whitchurch } 178d092c84bSBrandon Whitchurch 179d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSumGetSubspace_Sum(PetscSpace space, PetscInt s, PetscSpace *subspace) 180d71ae5a4SJacob Faibussowitsch { 181d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)space->data; 182d092c84bSBrandon Whitchurch PetscInt Ns = sum->numSumSpaces; 183d092c84bSBrandon Whitchurch 184d092c84bSBrandon Whitchurch PetscFunctionBegin; 18508401ef6SPierre Jolivet PetscCheck(Ns >= 0, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_WRONGSTATE, "Must call PetscSpaceSumSetNumSubspaces() first"); 1861dca8a05SBarry Smith PetscCheck(s >= 0 && s < Ns, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_OUTOFRANGE, "Invalid subspace number %" PetscInt_FMT, s); 187d092c84bSBrandon Whitchurch 188d092c84bSBrandon Whitchurch *subspace = sum->sumspaces[s]; 189d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 190d092c84bSBrandon Whitchurch } 191d092c84bSBrandon Whitchurch 192d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSumSetSubspace_Sum(PetscSpace space, PetscInt s, PetscSpace subspace) 193d71ae5a4SJacob Faibussowitsch { 194d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)space->data; 195d092c84bSBrandon Whitchurch PetscInt Ns = sum->numSumSpaces; 196d092c84bSBrandon Whitchurch 197d092c84bSBrandon Whitchurch PetscFunctionBegin; 19828b400f6SJacob Faibussowitsch PetscCheck(!sum->setupCalled, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_WRONGSTATE, "Cannot change subspace after setup called"); 19908401ef6SPierre Jolivet PetscCheck(Ns >= 0, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_WRONGSTATE, "Must call PetscSpaceSumSetNumSubspaces() first"); 2001dca8a05SBarry Smith PetscCheck(s >= 0 && s < Ns, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_OUTOFRANGE, "Invalid subspace number %" PetscInt_FMT, s); 201d092c84bSBrandon Whitchurch 2029566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)subspace)); 2039566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&sum->sumspaces[s])); 204d092c84bSBrandon Whitchurch sum->sumspaces[s] = subspace; 205d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 206d092c84bSBrandon Whitchurch } 207d092c84bSBrandon Whitchurch 208d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSetFromOptions_Sum(PetscSpace sp, PetscOptionItems *PetscOptionsObject) 209d71ae5a4SJacob Faibussowitsch { 210d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 211d092c84bSBrandon Whitchurch PetscInt Ns, Nc, Nv, deg, i; 212d092c84bSBrandon Whitchurch PetscBool concatenate = PETSC_TRUE; 213d092c84bSBrandon Whitchurch const char *prefix; 214d092c84bSBrandon Whitchurch 215d092c84bSBrandon Whitchurch PetscFunctionBegin; 2169566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sp, &Nv)); 217d092c84bSBrandon Whitchurch if (!Nv) PetscFunctionReturn(0); 2189566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(sp, &Nc)); 2199566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumGetNumSubspaces(sp, &Ns)); 2209566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(sp, °, NULL)); 221d092c84bSBrandon Whitchurch Ns = (Ns == PETSC_DEFAULT) ? 1 : Ns; 222d092c84bSBrandon Whitchurch 223d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "PetscSpace sum options"); 2249566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-petscspace_sum_spaces", "The number of subspaces", "PetscSpaceSumSetNumSubspaces", Ns, &Ns, NULL, 0)); 2259371c9d4SSatish Balay PetscCall(PetscOptionsBool("-petscspace_sum_concatenate", "Subspaces are concatenated components of the final space", "PetscSpaceSumSetFromOptions", concatenate, &concatenate, NULL)); 226d0609cedSBarry Smith PetscOptionsHeadEnd(); 227d092c84bSBrandon Whitchurch 2281dca8a05SBarry 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); 22948a46eb9SPierre Jolivet if (Ns != sum->numSumSpaces) PetscCall(PetscSpaceSumSetNumSubspaces(sp, Ns)); 2309566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)sp, &prefix)); 231d092c84bSBrandon Whitchurch for (i = 0; i < Ns; ++i) { 232d092c84bSBrandon Whitchurch PetscInt sNv; 233d092c84bSBrandon Whitchurch PetscSpace subspace; 234d092c84bSBrandon Whitchurch 2359566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumGetSubspace(sp, i, &subspace)); 236d092c84bSBrandon Whitchurch if (!subspace) { 237d092c84bSBrandon Whitchurch char subspacePrefix[256]; 238d092c84bSBrandon Whitchurch 2399566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(PetscObjectComm((PetscObject)sp), &subspace)); 2409566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)subspace, prefix)); 24163a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(subspacePrefix, 256, "sumcomp_%" PetscInt_FMT "_", i)); 2429566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)subspace, subspacePrefix)); 2431baa6e33SBarry Smith } else PetscCall(PetscObjectReference((PetscObject)subspace)); 2449566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetFromOptions(subspace)); 2459566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(subspace, &sNv)); 24663a3b9bcSJacob Faibussowitsch PetscCheck(sNv, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_WRONGSTATE, "Subspace %" PetscInt_FMT " has not been set properly, number of variables is 0.", i); 2479566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetSubspace(sp, i, subspace)); 2489566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&subspace)); 249d092c84bSBrandon Whitchurch } 250d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 251d092c84bSBrandon Whitchurch } 252d092c84bSBrandon Whitchurch 253d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSetUp_Sum(PetscSpace sp) 254d71ae5a4SJacob Faibussowitsch { 255d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 256d092c84bSBrandon Whitchurch PetscBool concatenate = PETSC_TRUE; 257642c7897SToby Isaac PetscBool uniform; 258642c7897SToby Isaac PetscInt Nv, Ns, Nc, i, sum_Nc = 0, deg = PETSC_MAX_INT, maxDeg = PETSC_MIN_INT; 259642c7897SToby Isaac PetscInt minNc, maxNc; 260d092c84bSBrandon Whitchurch 261d092c84bSBrandon Whitchurch PetscFunctionBegin; 262d092c84bSBrandon Whitchurch if (sum->setupCalled) PetscFunctionReturn(0); 263d092c84bSBrandon Whitchurch 2649566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sp, &Nv)); 2659566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(sp, &Nc)); 2669566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumGetNumSubspaces(sp, &Ns)); 267d092c84bSBrandon Whitchurch if (Ns == PETSC_DEFAULT) { 268d092c84bSBrandon Whitchurch Ns = 1; 2699566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetNumSubspaces(sp, Ns)); 270d092c84bSBrandon Whitchurch } 27163a3b9bcSJacob Faibussowitsch PetscCheck(Ns >= 0, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_OUTOFRANGE, "Cannot have %" PetscInt_FMT " subspaces", Ns); 272642c7897SToby Isaac uniform = PETSC_TRUE; 273642c7897SToby Isaac if (Ns) { 274642c7897SToby Isaac PetscSpace s0; 275d092c84bSBrandon Whitchurch 2769566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumGetSubspace(sp, 0, &s0)); 277642c7897SToby Isaac for (PetscInt i = 1; i < Ns; i++) { 278642c7897SToby Isaac PetscSpace si; 279642c7897SToby Isaac 2809566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumGetSubspace(sp, i, &si)); 281642c7897SToby Isaac if (si != s0) { 282642c7897SToby Isaac uniform = PETSC_FALSE; 283642c7897SToby Isaac break; 284642c7897SToby Isaac } 285642c7897SToby Isaac } 286642c7897SToby Isaac } 287642c7897SToby Isaac 288642c7897SToby Isaac minNc = Nc; 289642c7897SToby Isaac maxNc = Nc; 290d092c84bSBrandon Whitchurch for (i = 0; i < Ns; ++i) { 291d092c84bSBrandon Whitchurch PetscInt sNv, sNc, iDeg, iMaxDeg; 292d092c84bSBrandon Whitchurch PetscSpace si; 293d092c84bSBrandon Whitchurch 2949566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumGetSubspace(sp, i, &si)); 2959566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(si)); 2969566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(si, &sNv)); 29763a3b9bcSJacob 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); 2989566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(si, &sNc)); 299d092c84bSBrandon Whitchurch if (i == 0 && sNc == Nc) concatenate = PETSC_FALSE; 300642c7897SToby Isaac minNc = PetscMin(minNc, sNc); 301642c7897SToby Isaac maxNc = PetscMax(maxNc, sNc); 302d092c84bSBrandon Whitchurch sum_Nc += sNc; 3039566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumGetSubspace(sp, i, &si)); 3049566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(si, &iDeg, &iMaxDeg)); 305642c7897SToby Isaac deg = PetscMin(deg, iDeg); 306d092c84bSBrandon Whitchurch maxDeg = PetscMax(maxDeg, iMaxDeg); 307d092c84bSBrandon Whitchurch } 308d092c84bSBrandon Whitchurch 3097a46b595SBarry 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); 3107a46b595SBarry 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."); 311d092c84bSBrandon Whitchurch 312d092c84bSBrandon Whitchurch sp->degree = deg; 313d092c84bSBrandon Whitchurch sp->maxDegree = maxDeg; 314d092c84bSBrandon Whitchurch sum->concatenate = concatenate; 315642c7897SToby Isaac sum->uniform = uniform; 316d092c84bSBrandon Whitchurch sum->setupCalled = PETSC_TRUE; 317d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 318d092c84bSBrandon Whitchurch } 319d092c84bSBrandon Whitchurch 320d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSumView_Ascii(PetscSpace sp, PetscViewer v) 321d71ae5a4SJacob Faibussowitsch { 322d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 323d092c84bSBrandon Whitchurch PetscBool concatenate = sum->concatenate; 324d092c84bSBrandon Whitchurch PetscInt i, Ns = sum->numSumSpaces; 325d092c84bSBrandon Whitchurch 326d092c84bSBrandon Whitchurch PetscFunctionBegin; 3271baa6e33SBarry Smith if (concatenate) PetscCall(PetscViewerASCIIPrintf(v, "Sum space of %" PetscInt_FMT " concatenated subspaces%s\n", Ns, sum->uniform ? " (all identical)" : "")); 3281baa6e33SBarry Smith else PetscCall(PetscViewerASCIIPrintf(v, "Sum space of %" PetscInt_FMT " subspaces%s\n", Ns, sum->uniform ? " (all identical)" : "")); 329642c7897SToby Isaac for (i = 0; i < (sum->uniform ? (Ns > 0 ? 1 : 0) : Ns); ++i) { 3309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(v)); 3319566063dSJacob Faibussowitsch PetscCall(PetscSpaceView(sum->sumspaces[i], v)); 3329566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(v)); 333d092c84bSBrandon Whitchurch } 334d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 335d092c84bSBrandon Whitchurch } 336d092c84bSBrandon Whitchurch 337d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceView_Sum(PetscSpace sp, PetscViewer viewer) 338d71ae5a4SJacob Faibussowitsch { 339d092c84bSBrandon Whitchurch PetscBool iascii; 340d092c84bSBrandon Whitchurch 341d092c84bSBrandon Whitchurch PetscFunctionBegin; 3429566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 3431baa6e33SBarry Smith if (iascii) PetscCall(PetscSpaceSumView_Ascii(sp, viewer)); 344d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 345d092c84bSBrandon Whitchurch } 346d092c84bSBrandon Whitchurch 347d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceDestroy_Sum(PetscSpace sp) 348d71ae5a4SJacob Faibussowitsch { 349d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 350d092c84bSBrandon Whitchurch PetscInt i, Ns = sum->numSumSpaces; 351d092c84bSBrandon Whitchurch 352d092c84bSBrandon Whitchurch PetscFunctionBegin; 35348a46eb9SPierre Jolivet for (i = 0; i < Ns; ++i) PetscCall(PetscSpaceDestroy(&sum->sumspaces[i])); 3549566063dSJacob Faibussowitsch PetscCall(PetscFree(sum->sumspaces)); 355642c7897SToby Isaac if (sum->heightsubspaces) { 356642c7897SToby Isaac PetscInt d; 357642c7897SToby Isaac 358642c7897SToby Isaac /* sp->Nv is the spatial dimension, so it is equal to the number 359642c7897SToby Isaac * of subspaces on higher co-dimension points */ 36048a46eb9SPierre Jolivet for (d = 0; d < sp->Nv; ++d) PetscCall(PetscSpaceDestroy(&sum->heightsubspaces[d])); 361642c7897SToby Isaac } 3629566063dSJacob Faibussowitsch PetscCall(PetscFree(sum->heightsubspaces)); 3639566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetSubspace_C", NULL)); 3649566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetSubspace_C", NULL)); 3659566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetNumSubspaces_C", NULL)); 3669566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetNumSubspaces_C", NULL)); 3672e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetConcatenate_C", NULL)); 3682e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetConcatenate_C", NULL)); 3699566063dSJacob Faibussowitsch PetscCall(PetscFree(sum)); 370d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 371d092c84bSBrandon Whitchurch } 372d092c84bSBrandon Whitchurch 373d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceGetDimension_Sum(PetscSpace sp, PetscInt *dim) 374d71ae5a4SJacob Faibussowitsch { 375d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 376d092c84bSBrandon Whitchurch PetscInt i, d = 0, Ns = sum->numSumSpaces; 377d092c84bSBrandon Whitchurch 378d092c84bSBrandon Whitchurch PetscFunctionBegin; 379642c7897SToby Isaac if (!sum->setupCalled) { 3809566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sp)); 3819566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDimension(sp, dim)); 382642c7897SToby Isaac PetscFunctionReturn(0); 383642c7897SToby Isaac } 384d092c84bSBrandon Whitchurch 385d092c84bSBrandon Whitchurch for (i = 0; i < Ns; ++i) { 386d092c84bSBrandon Whitchurch PetscInt id; 387d092c84bSBrandon Whitchurch 3889566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDimension(sum->sumspaces[i], &id)); 389d092c84bSBrandon Whitchurch d += id; 390d092c84bSBrandon Whitchurch } 391d092c84bSBrandon Whitchurch 392d092c84bSBrandon Whitchurch *dim = d; 393d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 394d092c84bSBrandon Whitchurch } 395d092c84bSBrandon Whitchurch 396d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceEvaluate_Sum(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[]) 397d71ae5a4SJacob Faibussowitsch { 398d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 399d092c84bSBrandon Whitchurch PetscBool concatenate = sum->concatenate; 400d092c84bSBrandon Whitchurch DM dm = sp->dm; 401d092c84bSBrandon Whitchurch PetscInt Nc = sp->Nc, Nv = sp->Nv, Ns = sum->numSumSpaces; 402d092c84bSBrandon Whitchurch PetscInt i, s, offset, ncoffset, pdimfull, numelB, numelD, numelH; 403d092c84bSBrandon Whitchurch PetscReal *sB = NULL, *sD = NULL, *sH = NULL; 404d092c84bSBrandon Whitchurch 405d092c84bSBrandon Whitchurch PetscFunctionBegin; 406d092c84bSBrandon Whitchurch if (!sum->setupCalled) { 4079566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sp)); 4089566063dSJacob Faibussowitsch PetscCall(PetscSpaceEvaluate(sp, npoints, points, B, D, H)); 409642c7897SToby Isaac PetscFunctionReturn(0); 410d092c84bSBrandon Whitchurch } 4119566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDimension(sp, &pdimfull)); 412d092c84bSBrandon Whitchurch numelB = npoints * pdimfull * Nc; 413d092c84bSBrandon Whitchurch numelD = numelB * Nv; 414d092c84bSBrandon Whitchurch numelH = numelD * Nv; 41548a46eb9SPierre Jolivet if (B || D || H) PetscCall(DMGetWorkArray(dm, numelB, MPIU_REAL, &sB)); 41648a46eb9SPierre Jolivet if (D || H) PetscCall(DMGetWorkArray(dm, numelD, MPIU_REAL, &sD)); 41748a46eb9SPierre Jolivet if (H) PetscCall(DMGetWorkArray(dm, numelH, MPIU_REAL, &sH)); 418d092c84bSBrandon Whitchurch if (B) 419d092c84bSBrandon Whitchurch for (i = 0; i < numelB; ++i) B[i] = 0.; 420d092c84bSBrandon Whitchurch if (D) 421d092c84bSBrandon Whitchurch for (i = 0; i < numelD; ++i) D[i] = 0.; 422d092c84bSBrandon Whitchurch if (H) 423d092c84bSBrandon Whitchurch for (i = 0; i < numelH; ++i) H[i] = 0.; 424d092c84bSBrandon Whitchurch 425d092c84bSBrandon Whitchurch for (s = 0, offset = 0, ncoffset = 0; s < Ns; ++s) { 426d092c84bSBrandon Whitchurch PetscInt sNv, spdim, sNc, p; 427d092c84bSBrandon Whitchurch 4289566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sum->sumspaces[s], &sNv)); 4299566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(sum->sumspaces[s], &sNc)); 4309566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDimension(sum->sumspaces[s], &spdim)); 4311dca8a05SBarry Smith PetscCheck(offset + spdim <= pdimfull, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_OUTOFRANGE, "Subspace dimensions exceed target space dimension."); 43248a46eb9SPierre Jolivet if (s == 0 || !sum->uniform) PetscCall(PetscSpaceEvaluate(sum->sumspaces[s], npoints, points, sB, sD, sH)); 433d092c84bSBrandon Whitchurch if (B || D || H) { 434d092c84bSBrandon Whitchurch for (p = 0; p < npoints; ++p) { 435d092c84bSBrandon Whitchurch PetscInt j; 436d092c84bSBrandon Whitchurch 437d092c84bSBrandon Whitchurch for (j = 0; j < spdim; ++j) { 438d092c84bSBrandon Whitchurch PetscInt c; 439d092c84bSBrandon Whitchurch 440d092c84bSBrandon Whitchurch for (c = 0; c < sNc; ++c) { 441d092c84bSBrandon Whitchurch PetscInt compoffset, BInd, sBInd; 442d092c84bSBrandon Whitchurch 443d092c84bSBrandon Whitchurch compoffset = concatenate ? c + ncoffset : c; 444d092c84bSBrandon Whitchurch BInd = (p * pdimfull + j + offset) * Nc + compoffset; 445d092c84bSBrandon Whitchurch sBInd = (p * spdim + j) * sNc + c; 446642c7897SToby Isaac if (B) B[BInd] = sB[sBInd]; 447d092c84bSBrandon Whitchurch if (D || H) { 448d092c84bSBrandon Whitchurch PetscInt v; 449d092c84bSBrandon Whitchurch 450d092c84bSBrandon Whitchurch for (v = 0; v < Nv; ++v) { 451d092c84bSBrandon Whitchurch PetscInt DInd, sDInd; 452d092c84bSBrandon Whitchurch 453d092c84bSBrandon Whitchurch DInd = BInd * Nv + v; 454d092c84bSBrandon Whitchurch sDInd = sBInd * Nv + v; 455642c7897SToby Isaac if (D) D[DInd] = sD[sDInd]; 456d092c84bSBrandon Whitchurch if (H) { 457d092c84bSBrandon Whitchurch PetscInt v2; 458d092c84bSBrandon Whitchurch 459d092c84bSBrandon Whitchurch for (v2 = 0; v2 < Nv; ++v2) { 460d092c84bSBrandon Whitchurch PetscInt HInd, sHInd; 461d092c84bSBrandon Whitchurch 462d092c84bSBrandon Whitchurch HInd = DInd * Nv + v2; 463d092c84bSBrandon Whitchurch sHInd = sDInd * Nv + v2; 464642c7897SToby Isaac H[HInd] = sH[sHInd]; 465d092c84bSBrandon Whitchurch } 466d092c84bSBrandon Whitchurch } 467d092c84bSBrandon Whitchurch } 468d092c84bSBrandon Whitchurch } 469d092c84bSBrandon Whitchurch } 470d092c84bSBrandon Whitchurch } 471d092c84bSBrandon Whitchurch } 472d092c84bSBrandon Whitchurch } 473d092c84bSBrandon Whitchurch offset += spdim; 474d092c84bSBrandon Whitchurch ncoffset += sNc; 475d092c84bSBrandon Whitchurch } 476d092c84bSBrandon Whitchurch 47748a46eb9SPierre Jolivet if (H) PetscCall(DMRestoreWorkArray(dm, numelH, MPIU_REAL, &sH)); 47848a46eb9SPierre Jolivet if (D || H) PetscCall(DMRestoreWorkArray(dm, numelD, MPIU_REAL, &sD)); 47948a46eb9SPierre Jolivet if (B || D || H) PetscCall(DMRestoreWorkArray(dm, numelB, MPIU_REAL, &sB)); 480d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 481d092c84bSBrandon Whitchurch } 482d092c84bSBrandon Whitchurch 483d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceGetHeightSubspace_Sum(PetscSpace sp, PetscInt height, PetscSpace *subsp) 484d71ae5a4SJacob Faibussowitsch { 485642c7897SToby Isaac PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 486642c7897SToby Isaac PetscInt Nc, dim, order; 487642c7897SToby Isaac PetscBool tensor; 488642c7897SToby Isaac 489642c7897SToby Isaac PetscFunctionBegin; 4909566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(sp, &Nc)); 4919566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sp, &dim)); 4929566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(sp, &order, NULL)); 4939566063dSJacob Faibussowitsch PetscCall(PetscSpacePolynomialGetTensor(sp, &tensor)); 4941dca8a05SBarry 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); 4959566063dSJacob Faibussowitsch if (!sum->heightsubspaces) PetscCall(PetscCalloc1(dim, &sum->heightsubspaces)); 496642c7897SToby Isaac if (height <= dim) { 497642c7897SToby Isaac if (!sum->heightsubspaces[height - 1]) { 498642c7897SToby Isaac PetscSpace sub; 499642c7897SToby Isaac const char *name; 500642c7897SToby Isaac 5019566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(PetscObjectComm((PetscObject)sp), &sub)); 5029566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sp, &name)); 5039566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)sub, name)); 5049566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(sub, PETSCSPACESUM)); 5059566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetNumSubspaces(sub, sum->numSumSpaces)); 5069566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetConcatenate(sub, sum->concatenate)); 5079566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(sub, Nc)); 5089566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(sub, dim - height)); 509642c7897SToby Isaac for (PetscInt i = 0; i < sum->numSumSpaces; i++) { 510642c7897SToby Isaac PetscSpace subh; 511642c7897SToby Isaac 5129566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetHeightSubspace(sum->sumspaces[i], height, &subh)); 5139566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetSubspace(sub, i, subh)); 514642c7897SToby Isaac } 5159566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sub)); 516642c7897SToby Isaac sum->heightsubspaces[height - 1] = sub; 517642c7897SToby Isaac } 518642c7897SToby Isaac *subsp = sum->heightsubspaces[height - 1]; 519642c7897SToby Isaac } else { 520642c7897SToby Isaac *subsp = NULL; 521642c7897SToby Isaac } 522642c7897SToby Isaac PetscFunctionReturn(0); 523642c7897SToby Isaac } 524642c7897SToby Isaac 525d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceInitialize_Sum(PetscSpace sp) 526d71ae5a4SJacob Faibussowitsch { 527d092c84bSBrandon Whitchurch PetscFunctionBegin; 528d092c84bSBrandon Whitchurch sp->ops->setfromoptions = PetscSpaceSetFromOptions_Sum; 529d092c84bSBrandon Whitchurch sp->ops->setup = PetscSpaceSetUp_Sum; 530d092c84bSBrandon Whitchurch sp->ops->view = PetscSpaceView_Sum; 531d092c84bSBrandon Whitchurch sp->ops->destroy = PetscSpaceDestroy_Sum; 532d092c84bSBrandon Whitchurch sp->ops->getdimension = PetscSpaceGetDimension_Sum; 533d092c84bSBrandon Whitchurch sp->ops->evaluate = PetscSpaceEvaluate_Sum; 534642c7897SToby Isaac sp->ops->getheightsubspace = PetscSpaceGetHeightSubspace_Sum; 535d092c84bSBrandon Whitchurch 5369566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetNumSubspaces_C", PetscSpaceSumGetNumSubspaces_Sum)); 5379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetNumSubspaces_C", PetscSpaceSumSetNumSubspaces_Sum)); 5389566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetSubspace_C", PetscSpaceSumGetSubspace_Sum)); 5399566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetSubspace_C", PetscSpaceSumSetSubspace_Sum)); 5409566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetConcatenate_C", PetscSpaceSumGetConcatenate_Sum)); 5419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetConcatenate_C", PetscSpaceSumSetConcatenate_Sum)); 542d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 543d092c84bSBrandon Whitchurch } 544d092c84bSBrandon Whitchurch 545d092c84bSBrandon Whitchurch /*MC 546*dce8aebaSBarry Smith PETSCSPACESUM = "sum" - A `PetscSpace` object that encapsulates a sum of subspaces. 547d092c84bSBrandon Whitchurch That sum can either be direct or concatenate a concatenation. For example if A and B are spaces each with 2 components, 548d092c84bSBrandon 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 549d092c84bSBrandon Whitchurch same number of variables. 550d092c84bSBrandon Whitchurch 551d092c84bSBrandon Whitchurch Level: intermediate 552d092c84bSBrandon Whitchurch 553*dce8aebaSBarry Smith .seealso: `PetscSpace`, `PetscSpaceType`, `PetscSpaceCreate()`, `PetscSpaceSetType()` 554d092c84bSBrandon Whitchurch M*/ 555d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscSpaceCreate_Sum(PetscSpace sp) 556d71ae5a4SJacob Faibussowitsch { 557d092c84bSBrandon Whitchurch PetscSpace_Sum *sum; 558d092c84bSBrandon Whitchurch 559d092c84bSBrandon Whitchurch PetscFunctionBegin; 560d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 5614dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&sum)); 562642c7897SToby Isaac sum->numSumSpaces = PETSC_DEFAULT; 563d092c84bSBrandon Whitchurch sp->data = sum; 5649566063dSJacob Faibussowitsch PetscCall(PetscSpaceInitialize_Sum(sp)); 565d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 566d092c84bSBrandon Whitchurch } 567d092c84bSBrandon Whitchurch 568d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscSpaceCreateSum(PetscInt numSubspaces, const PetscSpace subspaces[], PetscBool concatenate, PetscSpace *sumSpace) 569d71ae5a4SJacob Faibussowitsch { 570d092c84bSBrandon Whitchurch PetscInt i, Nv, Nc = 0; 571d092c84bSBrandon Whitchurch 572d092c84bSBrandon Whitchurch PetscFunctionBegin; 5731baa6e33SBarry Smith if (sumSpace) PetscCall(PetscSpaceDestroy(sumSpace)); 5749566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(PetscObjectComm((PetscObject)subspaces[0]), sumSpace)); 5759566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(*sumSpace, PETSCSPACESUM)); 5769566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetNumSubspaces(*sumSpace, numSubspaces)); 5779566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetConcatenate(*sumSpace, concatenate)); 578d092c84bSBrandon Whitchurch for (i = 0; i < numSubspaces; ++i) { 579d092c84bSBrandon Whitchurch PetscInt sNc; 580d092c84bSBrandon Whitchurch 5819566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetSubspace(*sumSpace, i, subspaces[i])); 5829566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(subspaces[i], &sNc)); 583d092c84bSBrandon Whitchurch if (concatenate) Nc += sNc; 584d092c84bSBrandon Whitchurch else Nc = sNc; 585d092c84bSBrandon Whitchurch } 5869566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(subspaces[0], &Nv)); 5879566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(*sumSpace, Nc)); 5889566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(*sumSpace, Nv)); 5899566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(*sumSpace)); 590d092c84bSBrandon Whitchurch 591d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 592d092c84bSBrandon Whitchurch } 593