1d092c84bSBrandon Whitchurch #include <petsc/private/petscfeimpl.h> /*I "petscfe.h" I*/ 2*b24fb147SBarry Smith 3d092c84bSBrandon Whitchurch /*@ 4*b24fb147SBarry Smith PetscSpaceSumGetNumSubspaces - Get the number of spaces in the sum space 5d092c84bSBrandon Whitchurch 6d092c84bSBrandon Whitchurch Input Parameter: 7d092c84bSBrandon Whitchurch . sp - the function space object 8d092c84bSBrandon Whitchurch 9d092c84bSBrandon Whitchurch Output Parameter: 10d092c84bSBrandon Whitchurch . numSumSpaces - the number of spaces 11d092c84bSBrandon Whitchurch 12d092c84bSBrandon Whitchurch Level: intermediate 13d092c84bSBrandon Whitchurch 14*b24fb147SBarry Smith Note: 15*b24fb147SBarry Smith The name NumSubspaces is slightly misleading because it is actually getting the number of defining spaces of the sum, not a number of Subspaces of it 16*b24fb147SBarry Smith 17dce8aebaSBarry Smith .seealso: `PETSCSPACESUM`, `PetscSpace`, `PetscSpaceSumSetNumSubspaces()`, `PetscSpaceSetDegree()`, `PetscSpaceSetNumVariables()` 18d092c84bSBrandon Whitchurch @*/ 19d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSpaceSumGetNumSubspaces(PetscSpace sp, PetscInt *numSumSpaces) 20d71ae5a4SJacob Faibussowitsch { 21d092c84bSBrandon Whitchurch PetscFunctionBegin; 22d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 23d092c84bSBrandon Whitchurch PetscValidIntPointer(numSumSpaces, 2); 24cac4c232SBarry Smith PetscTryMethod(sp, "PetscSpaceSumGetNumSubspaces_C", (PetscSpace, PetscInt *), (sp, numSumSpaces)); 253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26d092c84bSBrandon Whitchurch } 27d092c84bSBrandon Whitchurch 28d092c84bSBrandon Whitchurch /*@ 29*b24fb147SBarry Smith PetscSpaceSumSetNumSubspaces - Set the number of spaces in the sum space 30d092c84bSBrandon Whitchurch 31d092c84bSBrandon Whitchurch Input Parameters: 32d092c84bSBrandon Whitchurch + sp - the function space object 33d092c84bSBrandon Whitchurch - numSumSpaces - the number of spaces 34d092c84bSBrandon Whitchurch 35d092c84bSBrandon Whitchurch Level: intermediate 36d092c84bSBrandon Whitchurch 37*b24fb147SBarry Smith Note: 38*b24fb147SBarry Smith The name NumSubspaces is slightly misleading because it is actually setting the number of defining spaces of the sum, not a number of Subspaces of it 39*b24fb147SBarry Smith 40dce8aebaSBarry Smith .seealso: `PETSCSPACESUM`, `PetscSpace`, `PetscSpaceSumGetNumSubspaces()`, `PetscSpaceSetDegree()`, `PetscSpaceSetNumVariables()` 41d092c84bSBrandon Whitchurch @*/ 42d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSpaceSumSetNumSubspaces(PetscSpace sp, PetscInt numSumSpaces) 43d71ae5a4SJacob Faibussowitsch { 44d092c84bSBrandon Whitchurch PetscFunctionBegin; 45d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 46cac4c232SBarry Smith PetscTryMethod(sp, "PetscSpaceSumSetNumSubspaces_C", (PetscSpace, PetscInt), (sp, numSumSpaces)); 473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 48d092c84bSBrandon Whitchurch } 49d092c84bSBrandon Whitchurch 50d092c84bSBrandon Whitchurch /*@ 51d092c84bSBrandon Whitchurch PetscSpaceSumGetConcatenate - Get the concatenate flag for this space. 52d092c84bSBrandon 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, 53d092c84bSBrandon Whitchurch or direct sum space will have the same number of components as its subspaces. 54d092c84bSBrandon Whitchurch 552fe279fdSBarry Smith Input Parameter: 56d092c84bSBrandon Whitchurch . sp - the function space object 57d092c84bSBrandon Whitchurch 582fe279fdSBarry Smith Output Parameter: 59d092c84bSBrandon Whitchurch . concatenate - flag indicating whether subspaces are concatenated. 60d092c84bSBrandon Whitchurch 61d092c84bSBrandon Whitchurch Level: intermediate 62d092c84bSBrandon Whitchurch 63dce8aebaSBarry Smith .seealso: `PETSCSPACESUM`, `PetscSpace`, `PetscSpaceSumSetConcatenate()` 64d092c84bSBrandon Whitchurch @*/ 65d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSpaceSumGetConcatenate(PetscSpace sp, PetscBool *concatenate) 66d71ae5a4SJacob Faibussowitsch { 67d092c84bSBrandon Whitchurch PetscFunctionBegin; 68d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 69cac4c232SBarry Smith PetscTryMethod(sp, "PetscSpaceSumGetConcatenate_C", (PetscSpace, PetscBool *), (sp, concatenate)); 703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 71d092c84bSBrandon Whitchurch } 72d092c84bSBrandon Whitchurch 73d092c84bSBrandon Whitchurch /*@ 74d092c84bSBrandon Whitchurch PetscSpaceSumSetConcatenate - Sets the concatenate flag for this space. 75d092c84bSBrandon 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, 76d092c84bSBrandon Whitchurch or direct sum space will have the same number of components as its subspaces . 77d092c84bSBrandon Whitchurch 78d092c84bSBrandon Whitchurch Input Parameters: 79d092c84bSBrandon Whitchurch + sp - the function space object 80d092c84bSBrandon Whitchurch - concatenate - are subspaces concatenated components (true) or direct summands (false) 81d092c84bSBrandon Whitchurch 82d092c84bSBrandon Whitchurch Level: intermediate 83dce8aebaSBarry Smith 84dce8aebaSBarry Smith .seealso: `PETSCSPACESUM`, `PetscSpace`, `PetscSpaceSumGetConcatenate()` 85d092c84bSBrandon Whitchurch @*/ 86d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSpaceSumSetConcatenate(PetscSpace sp, PetscBool concatenate) 87d71ae5a4SJacob Faibussowitsch { 88d092c84bSBrandon Whitchurch PetscFunctionBegin; 89d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 90cac4c232SBarry Smith PetscTryMethod(sp, "PetscSpaceSumSetConcatenate_C", (PetscSpace, PetscBool), (sp, concatenate)); 913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 92d092c84bSBrandon Whitchurch } 93d092c84bSBrandon Whitchurch 94d092c84bSBrandon Whitchurch /*@ 95*b24fb147SBarry Smith PetscSpaceSumGetSubspace - Get a space in the sum space 96d092c84bSBrandon Whitchurch 97d092c84bSBrandon Whitchurch Input Parameters: 98d092c84bSBrandon Whitchurch + sp - the function space object 99d092c84bSBrandon Whitchurch - s - The space number 100d092c84bSBrandon Whitchurch 101d092c84bSBrandon Whitchurch Output Parameter: 102*b24fb147SBarry Smith . subsp - the `PetscSpace` 103d092c84bSBrandon Whitchurch 104d092c84bSBrandon Whitchurch Level: intermediate 105d092c84bSBrandon Whitchurch 106*b24fb147SBarry Smith Note: 107*b24fb147SBarry Smith The name GetSubspace is slightly misleading because it is actually getting one of the defining spaces of the sum, not a Subspace of it 108*b24fb147SBarry Smith 109dce8aebaSBarry Smith .seealso: `PETSCSPACESUM`, `PetscSpace`, `PetscSpaceSumSetSubspace()`, `PetscSpaceSetDegree()`, `PetscSpaceSetNumVariables()` 110d092c84bSBrandon Whitchurch @*/ 111d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSpaceSumGetSubspace(PetscSpace sp, PetscInt s, PetscSpace *subsp) 112d71ae5a4SJacob Faibussowitsch { 113d092c84bSBrandon Whitchurch PetscFunctionBegin; 114d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 115d092c84bSBrandon Whitchurch PetscValidPointer(subsp, 3); 116cac4c232SBarry Smith PetscTryMethod(sp, "PetscSpaceSumGetSubspace_C", (PetscSpace, PetscInt, PetscSpace *), (sp, s, subsp)); 1173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 118d092c84bSBrandon Whitchurch } 119d092c84bSBrandon Whitchurch 120d092c84bSBrandon Whitchurch /*@ 121*b24fb147SBarry Smith PetscSpaceSumSetSubspace - Set a space in the sum space 122d092c84bSBrandon Whitchurch 123d092c84bSBrandon Whitchurch Input Parameters: 124d092c84bSBrandon Whitchurch + sp - the function space object 125d092c84bSBrandon Whitchurch . s - The space number 126d092c84bSBrandon Whitchurch - subsp - the number of spaces 127d092c84bSBrandon Whitchurch 128d092c84bSBrandon Whitchurch Level: intermediate 129d092c84bSBrandon Whitchurch 130*b24fb147SBarry Smith Note: 131*b24fb147SBarry Smith The name SetSubspace is slightly misleading because it is actually setting one of the defining spaces of the sum, not a Subspace of it 132*b24fb147SBarry Smith 133dce8aebaSBarry Smith .seealso: `PETSCSPACESUM`, `PetscSpace`, `PetscSpaceSumGetSubspace()`, `PetscSpaceSetDegree()`, `PetscSpaceSetNumVariables()` 134d092c84bSBrandon Whitchurch @*/ 135d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSpaceSumSetSubspace(PetscSpace sp, PetscInt s, PetscSpace subsp) 136d71ae5a4SJacob Faibussowitsch { 137d092c84bSBrandon Whitchurch PetscFunctionBegin; 138d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 139d092c84bSBrandon Whitchurch if (subsp) PetscValidHeaderSpecific(subsp, PETSCSPACE_CLASSID, 3); 140cac4c232SBarry Smith PetscTryMethod(sp, "PetscSpaceSumSetSubspace_C", (PetscSpace, PetscInt, PetscSpace), (sp, s, subsp)); 1413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 142d092c84bSBrandon Whitchurch } 143d092c84bSBrandon Whitchurch 144d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSumGetNumSubspaces_Sum(PetscSpace space, PetscInt *numSumSpaces) 145d71ae5a4SJacob Faibussowitsch { 146d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)space->data; 147d092c84bSBrandon Whitchurch 148d092c84bSBrandon Whitchurch PetscFunctionBegin; 149d092c84bSBrandon Whitchurch *numSumSpaces = sum->numSumSpaces; 1503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 151d092c84bSBrandon Whitchurch } 152d092c84bSBrandon Whitchurch 153d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSumSetNumSubspaces_Sum(PetscSpace space, PetscInt numSumSpaces) 154d71ae5a4SJacob Faibussowitsch { 155d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)space->data; 156d092c84bSBrandon Whitchurch PetscInt Ns = sum->numSumSpaces; 157d092c84bSBrandon Whitchurch 158d092c84bSBrandon Whitchurch PetscFunctionBegin; 15928b400f6SJacob Faibussowitsch PetscCheck(!sum->setupCalled, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_WRONGSTATE, "Cannot change number of subspaces after setup called"); 1603ba16761SJacob Faibussowitsch if (numSumSpaces == Ns) PetscFunctionReturn(PETSC_SUCCESS); 161d092c84bSBrandon Whitchurch if (Ns >= 0) { 162d092c84bSBrandon Whitchurch PetscInt s; 16348a46eb9SPierre Jolivet for (s = 0; s < Ns; ++s) PetscCall(PetscSpaceDestroy(&sum->sumspaces[s])); 1649566063dSJacob Faibussowitsch PetscCall(PetscFree(sum->sumspaces)); 165d092c84bSBrandon Whitchurch } 166d092c84bSBrandon Whitchurch 167d092c84bSBrandon Whitchurch Ns = sum->numSumSpaces = numSumSpaces; 1689566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Ns, &sum->sumspaces)); 1693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 170d092c84bSBrandon Whitchurch } 171d092c84bSBrandon Whitchurch 172d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSumGetConcatenate_Sum(PetscSpace sp, PetscBool *concatenate) 173d71ae5a4SJacob Faibussowitsch { 174d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 175d092c84bSBrandon Whitchurch 176d092c84bSBrandon Whitchurch PetscFunctionBegin; 177d092c84bSBrandon Whitchurch *concatenate = sum->concatenate; 1783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 179d092c84bSBrandon Whitchurch } 180d092c84bSBrandon Whitchurch 181d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSumSetConcatenate_Sum(PetscSpace sp, PetscBool concatenate) 182d71ae5a4SJacob Faibussowitsch { 183d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 184d092c84bSBrandon Whitchurch 185d092c84bSBrandon Whitchurch PetscFunctionBegin; 18628b400f6SJacob Faibussowitsch PetscCheck(!sum->setupCalled, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_WRONGSTATE, "Cannot change space concatenation after setup called."); 187d092c84bSBrandon Whitchurch 188d092c84bSBrandon Whitchurch sum->concatenate = concatenate; 1893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 190d092c84bSBrandon Whitchurch } 191d092c84bSBrandon Whitchurch 192d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSumGetSubspace_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; 19808401ef6SPierre Jolivet PetscCheck(Ns >= 0, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_WRONGSTATE, "Must call PetscSpaceSumSetNumSubspaces() first"); 1991dca8a05SBarry Smith PetscCheck(s >= 0 && s < Ns, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_OUTOFRANGE, "Invalid subspace number %" PetscInt_FMT, s); 200d092c84bSBrandon Whitchurch 201d092c84bSBrandon Whitchurch *subspace = sum->sumspaces[s]; 2023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 203d092c84bSBrandon Whitchurch } 204d092c84bSBrandon Whitchurch 205d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSumSetSubspace_Sum(PetscSpace space, PetscInt s, PetscSpace subspace) 206d71ae5a4SJacob Faibussowitsch { 207d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)space->data; 208d092c84bSBrandon Whitchurch PetscInt Ns = sum->numSumSpaces; 209d092c84bSBrandon Whitchurch 210d092c84bSBrandon Whitchurch PetscFunctionBegin; 21128b400f6SJacob Faibussowitsch PetscCheck(!sum->setupCalled, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_WRONGSTATE, "Cannot change subspace after setup called"); 21208401ef6SPierre Jolivet PetscCheck(Ns >= 0, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_WRONGSTATE, "Must call PetscSpaceSumSetNumSubspaces() first"); 2131dca8a05SBarry Smith PetscCheck(s >= 0 && s < Ns, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_OUTOFRANGE, "Invalid subspace number %" PetscInt_FMT, s); 214d092c84bSBrandon Whitchurch 2159566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)subspace)); 2169566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&sum->sumspaces[s])); 217d092c84bSBrandon Whitchurch sum->sumspaces[s] = subspace; 2183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 219d092c84bSBrandon Whitchurch } 220d092c84bSBrandon Whitchurch 221d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSetFromOptions_Sum(PetscSpace sp, PetscOptionItems *PetscOptionsObject) 222d71ae5a4SJacob Faibussowitsch { 223d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 224d092c84bSBrandon Whitchurch PetscInt Ns, Nc, Nv, deg, i; 225d092c84bSBrandon Whitchurch PetscBool concatenate = PETSC_TRUE; 226d092c84bSBrandon Whitchurch const char *prefix; 227d092c84bSBrandon Whitchurch 228d092c84bSBrandon Whitchurch PetscFunctionBegin; 2299566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sp, &Nv)); 2303ba16761SJacob Faibussowitsch if (!Nv) PetscFunctionReturn(PETSC_SUCCESS); 2319566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(sp, &Nc)); 2329566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumGetNumSubspaces(sp, &Ns)); 2339566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(sp, °, NULL)); 234d092c84bSBrandon Whitchurch Ns = (Ns == PETSC_DEFAULT) ? 1 : Ns; 235d092c84bSBrandon Whitchurch 236d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "PetscSpace sum options"); 2379566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-petscspace_sum_spaces", "The number of subspaces", "PetscSpaceSumSetNumSubspaces", Ns, &Ns, NULL, 0)); 2389371c9d4SSatish Balay PetscCall(PetscOptionsBool("-petscspace_sum_concatenate", "Subspaces are concatenated components of the final space", "PetscSpaceSumSetFromOptions", concatenate, &concatenate, NULL)); 239d0609cedSBarry Smith PetscOptionsHeadEnd(); 240d092c84bSBrandon Whitchurch 2411dca8a05SBarry 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); 24248a46eb9SPierre Jolivet if (Ns != sum->numSumSpaces) PetscCall(PetscSpaceSumSetNumSubspaces(sp, Ns)); 2439566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)sp, &prefix)); 244d092c84bSBrandon Whitchurch for (i = 0; i < Ns; ++i) { 245d092c84bSBrandon Whitchurch PetscInt sNv; 246d092c84bSBrandon Whitchurch PetscSpace subspace; 247d092c84bSBrandon Whitchurch 2489566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumGetSubspace(sp, i, &subspace)); 249d092c84bSBrandon Whitchurch if (!subspace) { 250d092c84bSBrandon Whitchurch char subspacePrefix[256]; 251d092c84bSBrandon Whitchurch 2529566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(PetscObjectComm((PetscObject)sp), &subspace)); 2539566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)subspace, prefix)); 25463a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(subspacePrefix, 256, "sumcomp_%" PetscInt_FMT "_", i)); 2559566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)subspace, subspacePrefix)); 2561baa6e33SBarry Smith } else PetscCall(PetscObjectReference((PetscObject)subspace)); 2579566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetFromOptions(subspace)); 2589566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(subspace, &sNv)); 25963a3b9bcSJacob Faibussowitsch PetscCheck(sNv, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_WRONGSTATE, "Subspace %" PetscInt_FMT " has not been set properly, number of variables is 0.", i); 2609566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetSubspace(sp, i, subspace)); 2619566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&subspace)); 262d092c84bSBrandon Whitchurch } 2633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 264d092c84bSBrandon Whitchurch } 265d092c84bSBrandon Whitchurch 266d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSetUp_Sum(PetscSpace sp) 267d71ae5a4SJacob Faibussowitsch { 268d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 269d092c84bSBrandon Whitchurch PetscBool concatenate = PETSC_TRUE; 270642c7897SToby Isaac PetscBool uniform; 271642c7897SToby Isaac PetscInt Nv, Ns, Nc, i, sum_Nc = 0, deg = PETSC_MAX_INT, maxDeg = PETSC_MIN_INT; 272642c7897SToby Isaac PetscInt minNc, maxNc; 273d092c84bSBrandon Whitchurch 274d092c84bSBrandon Whitchurch PetscFunctionBegin; 2753ba16761SJacob Faibussowitsch if (sum->setupCalled) PetscFunctionReturn(PETSC_SUCCESS); 276d092c84bSBrandon Whitchurch 2779566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sp, &Nv)); 2789566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(sp, &Nc)); 2799566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumGetNumSubspaces(sp, &Ns)); 280d092c84bSBrandon Whitchurch if (Ns == PETSC_DEFAULT) { 281d092c84bSBrandon Whitchurch Ns = 1; 2829566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetNumSubspaces(sp, Ns)); 283d092c84bSBrandon Whitchurch } 28463a3b9bcSJacob Faibussowitsch PetscCheck(Ns >= 0, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_OUTOFRANGE, "Cannot have %" PetscInt_FMT " subspaces", Ns); 285642c7897SToby Isaac uniform = PETSC_TRUE; 286642c7897SToby Isaac if (Ns) { 287642c7897SToby Isaac PetscSpace s0; 288d092c84bSBrandon Whitchurch 2899566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumGetSubspace(sp, 0, &s0)); 290642c7897SToby Isaac for (PetscInt i = 1; i < Ns; i++) { 291642c7897SToby Isaac PetscSpace si; 292642c7897SToby Isaac 2939566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumGetSubspace(sp, i, &si)); 294642c7897SToby Isaac if (si != s0) { 295642c7897SToby Isaac uniform = PETSC_FALSE; 296642c7897SToby Isaac break; 297642c7897SToby Isaac } 298642c7897SToby Isaac } 299642c7897SToby Isaac } 300642c7897SToby Isaac 301642c7897SToby Isaac minNc = Nc; 302642c7897SToby Isaac maxNc = Nc; 303d092c84bSBrandon Whitchurch for (i = 0; i < Ns; ++i) { 304d092c84bSBrandon Whitchurch PetscInt sNv, sNc, iDeg, iMaxDeg; 305d092c84bSBrandon Whitchurch PetscSpace si; 306d092c84bSBrandon Whitchurch 3079566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumGetSubspace(sp, i, &si)); 3089566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(si)); 3099566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(si, &sNv)); 31063a3b9bcSJacob 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); 3119566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(si, &sNc)); 312d092c84bSBrandon Whitchurch if (i == 0 && sNc == Nc) concatenate = PETSC_FALSE; 313642c7897SToby Isaac minNc = PetscMin(minNc, sNc); 314642c7897SToby Isaac maxNc = PetscMax(maxNc, sNc); 315d092c84bSBrandon Whitchurch sum_Nc += sNc; 3169566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumGetSubspace(sp, i, &si)); 3179566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(si, &iDeg, &iMaxDeg)); 318642c7897SToby Isaac deg = PetscMin(deg, iDeg); 319d092c84bSBrandon Whitchurch maxDeg = PetscMax(maxDeg, iMaxDeg); 320d092c84bSBrandon Whitchurch } 321d092c84bSBrandon Whitchurch 3227a46b595SBarry 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); 3237a46b595SBarry 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."); 324d092c84bSBrandon Whitchurch 325d092c84bSBrandon Whitchurch sp->degree = deg; 326d092c84bSBrandon Whitchurch sp->maxDegree = maxDeg; 327d092c84bSBrandon Whitchurch sum->concatenate = concatenate; 328642c7897SToby Isaac sum->uniform = uniform; 329d092c84bSBrandon Whitchurch sum->setupCalled = PETSC_TRUE; 3303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 331d092c84bSBrandon Whitchurch } 332d092c84bSBrandon Whitchurch 333d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSumView_Ascii(PetscSpace sp, PetscViewer v) 334d71ae5a4SJacob Faibussowitsch { 335d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 336d092c84bSBrandon Whitchurch PetscBool concatenate = sum->concatenate; 337d092c84bSBrandon Whitchurch PetscInt i, Ns = sum->numSumSpaces; 338d092c84bSBrandon Whitchurch 339d092c84bSBrandon Whitchurch PetscFunctionBegin; 3401baa6e33SBarry Smith if (concatenate) PetscCall(PetscViewerASCIIPrintf(v, "Sum space of %" PetscInt_FMT " concatenated subspaces%s\n", Ns, sum->uniform ? " (all identical)" : "")); 3411baa6e33SBarry Smith else PetscCall(PetscViewerASCIIPrintf(v, "Sum space of %" PetscInt_FMT " subspaces%s\n", Ns, sum->uniform ? " (all identical)" : "")); 342642c7897SToby Isaac for (i = 0; i < (sum->uniform ? (Ns > 0 ? 1 : 0) : Ns); ++i) { 3439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(v)); 3449566063dSJacob Faibussowitsch PetscCall(PetscSpaceView(sum->sumspaces[i], v)); 3459566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(v)); 346d092c84bSBrandon Whitchurch } 3473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 348d092c84bSBrandon Whitchurch } 349d092c84bSBrandon Whitchurch 350d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceView_Sum(PetscSpace sp, PetscViewer viewer) 351d71ae5a4SJacob Faibussowitsch { 352d092c84bSBrandon Whitchurch PetscBool iascii; 353d092c84bSBrandon Whitchurch 354d092c84bSBrandon Whitchurch PetscFunctionBegin; 3559566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 3561baa6e33SBarry Smith if (iascii) PetscCall(PetscSpaceSumView_Ascii(sp, viewer)); 3573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 358d092c84bSBrandon Whitchurch } 359d092c84bSBrandon Whitchurch 360d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceDestroy_Sum(PetscSpace sp) 361d71ae5a4SJacob Faibussowitsch { 362d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 363d092c84bSBrandon Whitchurch PetscInt i, Ns = sum->numSumSpaces; 364d092c84bSBrandon Whitchurch 365d092c84bSBrandon Whitchurch PetscFunctionBegin; 36648a46eb9SPierre Jolivet for (i = 0; i < Ns; ++i) PetscCall(PetscSpaceDestroy(&sum->sumspaces[i])); 3679566063dSJacob Faibussowitsch PetscCall(PetscFree(sum->sumspaces)); 368642c7897SToby Isaac if (sum->heightsubspaces) { 369642c7897SToby Isaac PetscInt d; 370642c7897SToby Isaac 371642c7897SToby Isaac /* sp->Nv is the spatial dimension, so it is equal to the number 372642c7897SToby Isaac * of subspaces on higher co-dimension points */ 37348a46eb9SPierre Jolivet for (d = 0; d < sp->Nv; ++d) PetscCall(PetscSpaceDestroy(&sum->heightsubspaces[d])); 374642c7897SToby Isaac } 3759566063dSJacob Faibussowitsch PetscCall(PetscFree(sum->heightsubspaces)); 3769566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetSubspace_C", NULL)); 3779566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetSubspace_C", NULL)); 3789566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetNumSubspaces_C", NULL)); 3799566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetNumSubspaces_C", NULL)); 3802e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetConcatenate_C", NULL)); 3812e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetConcatenate_C", NULL)); 3829566063dSJacob Faibussowitsch PetscCall(PetscFree(sum)); 3833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 384d092c84bSBrandon Whitchurch } 385d092c84bSBrandon Whitchurch 386d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceGetDimension_Sum(PetscSpace sp, PetscInt *dim) 387d71ae5a4SJacob Faibussowitsch { 388d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 389d092c84bSBrandon Whitchurch PetscInt i, d = 0, Ns = sum->numSumSpaces; 390d092c84bSBrandon Whitchurch 391d092c84bSBrandon Whitchurch PetscFunctionBegin; 392642c7897SToby Isaac if (!sum->setupCalled) { 3939566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sp)); 3949566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDimension(sp, dim)); 3953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 396642c7897SToby Isaac } 397d092c84bSBrandon Whitchurch 398d092c84bSBrandon Whitchurch for (i = 0; i < Ns; ++i) { 399d092c84bSBrandon Whitchurch PetscInt id; 400d092c84bSBrandon Whitchurch 4019566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDimension(sum->sumspaces[i], &id)); 402d092c84bSBrandon Whitchurch d += id; 403d092c84bSBrandon Whitchurch } 404d092c84bSBrandon Whitchurch 405d092c84bSBrandon Whitchurch *dim = d; 4063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 407d092c84bSBrandon Whitchurch } 408d092c84bSBrandon Whitchurch 409d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceEvaluate_Sum(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[]) 410d71ae5a4SJacob Faibussowitsch { 411d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 412d092c84bSBrandon Whitchurch PetscBool concatenate = sum->concatenate; 413d092c84bSBrandon Whitchurch DM dm = sp->dm; 414d092c84bSBrandon Whitchurch PetscInt Nc = sp->Nc, Nv = sp->Nv, Ns = sum->numSumSpaces; 415d092c84bSBrandon Whitchurch PetscInt i, s, offset, ncoffset, pdimfull, numelB, numelD, numelH; 416d092c84bSBrandon Whitchurch PetscReal *sB = NULL, *sD = NULL, *sH = NULL; 417d092c84bSBrandon Whitchurch 418d092c84bSBrandon Whitchurch PetscFunctionBegin; 419d092c84bSBrandon Whitchurch if (!sum->setupCalled) { 4209566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sp)); 4219566063dSJacob Faibussowitsch PetscCall(PetscSpaceEvaluate(sp, npoints, points, B, D, H)); 4223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 423d092c84bSBrandon Whitchurch } 4249566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDimension(sp, &pdimfull)); 425d092c84bSBrandon Whitchurch numelB = npoints * pdimfull * Nc; 426d092c84bSBrandon Whitchurch numelD = numelB * Nv; 427d092c84bSBrandon Whitchurch numelH = numelD * Nv; 42848a46eb9SPierre Jolivet if (B || D || H) PetscCall(DMGetWorkArray(dm, numelB, MPIU_REAL, &sB)); 42948a46eb9SPierre Jolivet if (D || H) PetscCall(DMGetWorkArray(dm, numelD, MPIU_REAL, &sD)); 43048a46eb9SPierre Jolivet if (H) PetscCall(DMGetWorkArray(dm, numelH, MPIU_REAL, &sH)); 431d092c84bSBrandon Whitchurch if (B) 432d092c84bSBrandon Whitchurch for (i = 0; i < numelB; ++i) B[i] = 0.; 433d092c84bSBrandon Whitchurch if (D) 434d092c84bSBrandon Whitchurch for (i = 0; i < numelD; ++i) D[i] = 0.; 435d092c84bSBrandon Whitchurch if (H) 436d092c84bSBrandon Whitchurch for (i = 0; i < numelH; ++i) H[i] = 0.; 437d092c84bSBrandon Whitchurch 438d092c84bSBrandon Whitchurch for (s = 0, offset = 0, ncoffset = 0; s < Ns; ++s) { 439d092c84bSBrandon Whitchurch PetscInt sNv, spdim, sNc, p; 440d092c84bSBrandon Whitchurch 4419566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sum->sumspaces[s], &sNv)); 4429566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(sum->sumspaces[s], &sNc)); 4439566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDimension(sum->sumspaces[s], &spdim)); 4441dca8a05SBarry Smith PetscCheck(offset + spdim <= pdimfull, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_OUTOFRANGE, "Subspace dimensions exceed target space dimension."); 44548a46eb9SPierre Jolivet if (s == 0 || !sum->uniform) PetscCall(PetscSpaceEvaluate(sum->sumspaces[s], npoints, points, sB, sD, sH)); 446d092c84bSBrandon Whitchurch if (B || D || H) { 447d092c84bSBrandon Whitchurch for (p = 0; p < npoints; ++p) { 448d092c84bSBrandon Whitchurch PetscInt j; 449d092c84bSBrandon Whitchurch 450d092c84bSBrandon Whitchurch for (j = 0; j < spdim; ++j) { 451d092c84bSBrandon Whitchurch PetscInt c; 452d092c84bSBrandon Whitchurch 453d092c84bSBrandon Whitchurch for (c = 0; c < sNc; ++c) { 454d092c84bSBrandon Whitchurch PetscInt compoffset, BInd, sBInd; 455d092c84bSBrandon Whitchurch 456d092c84bSBrandon Whitchurch compoffset = concatenate ? c + ncoffset : c; 457d092c84bSBrandon Whitchurch BInd = (p * pdimfull + j + offset) * Nc + compoffset; 458d092c84bSBrandon Whitchurch sBInd = (p * spdim + j) * sNc + c; 459642c7897SToby Isaac if (B) B[BInd] = sB[sBInd]; 460d092c84bSBrandon Whitchurch if (D || H) { 461d092c84bSBrandon Whitchurch PetscInt v; 462d092c84bSBrandon Whitchurch 463d092c84bSBrandon Whitchurch for (v = 0; v < Nv; ++v) { 464d092c84bSBrandon Whitchurch PetscInt DInd, sDInd; 465d092c84bSBrandon Whitchurch 466d092c84bSBrandon Whitchurch DInd = BInd * Nv + v; 467d092c84bSBrandon Whitchurch sDInd = sBInd * Nv + v; 468642c7897SToby Isaac if (D) D[DInd] = sD[sDInd]; 469d092c84bSBrandon Whitchurch if (H) { 470d092c84bSBrandon Whitchurch PetscInt v2; 471d092c84bSBrandon Whitchurch 472d092c84bSBrandon Whitchurch for (v2 = 0; v2 < Nv; ++v2) { 473d092c84bSBrandon Whitchurch PetscInt HInd, sHInd; 474d092c84bSBrandon Whitchurch 475d092c84bSBrandon Whitchurch HInd = DInd * Nv + v2; 476d092c84bSBrandon Whitchurch sHInd = sDInd * Nv + v2; 477642c7897SToby Isaac H[HInd] = sH[sHInd]; 478d092c84bSBrandon Whitchurch } 479d092c84bSBrandon Whitchurch } 480d092c84bSBrandon Whitchurch } 481d092c84bSBrandon Whitchurch } 482d092c84bSBrandon Whitchurch } 483d092c84bSBrandon Whitchurch } 484d092c84bSBrandon Whitchurch } 485d092c84bSBrandon Whitchurch } 486d092c84bSBrandon Whitchurch offset += spdim; 487d092c84bSBrandon Whitchurch ncoffset += sNc; 488d092c84bSBrandon Whitchurch } 489d092c84bSBrandon Whitchurch 49048a46eb9SPierre Jolivet if (H) PetscCall(DMRestoreWorkArray(dm, numelH, MPIU_REAL, &sH)); 49148a46eb9SPierre Jolivet if (D || H) PetscCall(DMRestoreWorkArray(dm, numelD, MPIU_REAL, &sD)); 49248a46eb9SPierre Jolivet if (B || D || H) PetscCall(DMRestoreWorkArray(dm, numelB, MPIU_REAL, &sB)); 4933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 494d092c84bSBrandon Whitchurch } 495d092c84bSBrandon Whitchurch 496d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceGetHeightSubspace_Sum(PetscSpace sp, PetscInt height, PetscSpace *subsp) 497d71ae5a4SJacob Faibussowitsch { 498642c7897SToby Isaac PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 499642c7897SToby Isaac PetscInt Nc, dim, order; 500642c7897SToby Isaac PetscBool tensor; 501642c7897SToby Isaac 502642c7897SToby Isaac PetscFunctionBegin; 5039566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(sp, &Nc)); 5049566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sp, &dim)); 5059566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(sp, &order, NULL)); 5069566063dSJacob Faibussowitsch PetscCall(PetscSpacePolynomialGetTensor(sp, &tensor)); 5071dca8a05SBarry 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); 5089566063dSJacob Faibussowitsch if (!sum->heightsubspaces) PetscCall(PetscCalloc1(dim, &sum->heightsubspaces)); 509642c7897SToby Isaac if (height <= dim) { 510642c7897SToby Isaac if (!sum->heightsubspaces[height - 1]) { 511642c7897SToby Isaac PetscSpace sub; 512642c7897SToby Isaac const char *name; 513642c7897SToby Isaac 5149566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(PetscObjectComm((PetscObject)sp), &sub)); 5159566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sp, &name)); 5169566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)sub, name)); 5179566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(sub, PETSCSPACESUM)); 5189566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetNumSubspaces(sub, sum->numSumSpaces)); 5199566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetConcatenate(sub, sum->concatenate)); 5209566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(sub, Nc)); 5219566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(sub, dim - height)); 522642c7897SToby Isaac for (PetscInt i = 0; i < sum->numSumSpaces; i++) { 523642c7897SToby Isaac PetscSpace subh; 524642c7897SToby Isaac 5259566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetHeightSubspace(sum->sumspaces[i], height, &subh)); 5269566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetSubspace(sub, i, subh)); 527642c7897SToby Isaac } 5289566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sub)); 529642c7897SToby Isaac sum->heightsubspaces[height - 1] = sub; 530642c7897SToby Isaac } 531642c7897SToby Isaac *subsp = sum->heightsubspaces[height - 1]; 532642c7897SToby Isaac } else { 533642c7897SToby Isaac *subsp = NULL; 534642c7897SToby Isaac } 5353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 536642c7897SToby Isaac } 537642c7897SToby Isaac 538d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceInitialize_Sum(PetscSpace sp) 539d71ae5a4SJacob Faibussowitsch { 540d092c84bSBrandon Whitchurch PetscFunctionBegin; 541d092c84bSBrandon Whitchurch sp->ops->setfromoptions = PetscSpaceSetFromOptions_Sum; 542d092c84bSBrandon Whitchurch sp->ops->setup = PetscSpaceSetUp_Sum; 543d092c84bSBrandon Whitchurch sp->ops->view = PetscSpaceView_Sum; 544d092c84bSBrandon Whitchurch sp->ops->destroy = PetscSpaceDestroy_Sum; 545d092c84bSBrandon Whitchurch sp->ops->getdimension = PetscSpaceGetDimension_Sum; 546d092c84bSBrandon Whitchurch sp->ops->evaluate = PetscSpaceEvaluate_Sum; 547642c7897SToby Isaac sp->ops->getheightsubspace = PetscSpaceGetHeightSubspace_Sum; 548d092c84bSBrandon Whitchurch 5499566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetNumSubspaces_C", PetscSpaceSumGetNumSubspaces_Sum)); 5509566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetNumSubspaces_C", PetscSpaceSumSetNumSubspaces_Sum)); 5519566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetSubspace_C", PetscSpaceSumGetSubspace_Sum)); 5529566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetSubspace_C", PetscSpaceSumSetSubspace_Sum)); 5539566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetConcatenate_C", PetscSpaceSumGetConcatenate_Sum)); 5549566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetConcatenate_C", PetscSpaceSumSetConcatenate_Sum)); 5553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 556d092c84bSBrandon Whitchurch } 557d092c84bSBrandon Whitchurch 558d092c84bSBrandon Whitchurch /*MC 559dce8aebaSBarry Smith PETSCSPACESUM = "sum" - A `PetscSpace` object that encapsulates a sum of subspaces. 560d092c84bSBrandon Whitchurch 561d092c84bSBrandon Whitchurch Level: intermediate 562d092c84bSBrandon Whitchurch 563*b24fb147SBarry Smith Note: 564*b24fb147SBarry Smith That sum can either be direct or a concatenation. For example if A and B are spaces each with 2 components, 565*b24fb147SBarry Smith 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 566*b24fb147SBarry Smith same number of variables. 567*b24fb147SBarry Smith 568*b24fb147SBarry Smith .seealso: `PetscSpace`, `PetscSpaceType`, `PetscSpaceCreate()`, `PetscSpaceSetType()`, `PetscSpaceSumGetNumSubspaces()`, `PetscSpaceSumSetNumSubspaces()`, 569*b24fb147SBarry Smith `PetscSpaceSumGetConcatenate()`, `PetscSpaceSumSetConcatenate()` 570d092c84bSBrandon Whitchurch M*/ 571d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscSpaceCreate_Sum(PetscSpace sp) 572d71ae5a4SJacob Faibussowitsch { 573d092c84bSBrandon Whitchurch PetscSpace_Sum *sum; 574d092c84bSBrandon Whitchurch 575d092c84bSBrandon Whitchurch PetscFunctionBegin; 576d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 5774dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&sum)); 578642c7897SToby Isaac sum->numSumSpaces = PETSC_DEFAULT; 579d092c84bSBrandon Whitchurch sp->data = sum; 5809566063dSJacob Faibussowitsch PetscCall(PetscSpaceInitialize_Sum(sp)); 5813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 582d092c84bSBrandon Whitchurch } 583d092c84bSBrandon Whitchurch 584d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscSpaceCreateSum(PetscInt numSubspaces, const PetscSpace subspaces[], PetscBool concatenate, PetscSpace *sumSpace) 585d71ae5a4SJacob Faibussowitsch { 586d092c84bSBrandon Whitchurch PetscInt i, Nv, Nc = 0; 587d092c84bSBrandon Whitchurch 588d092c84bSBrandon Whitchurch PetscFunctionBegin; 5891baa6e33SBarry Smith if (sumSpace) PetscCall(PetscSpaceDestroy(sumSpace)); 5909566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(PetscObjectComm((PetscObject)subspaces[0]), sumSpace)); 5919566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(*sumSpace, PETSCSPACESUM)); 5929566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetNumSubspaces(*sumSpace, numSubspaces)); 5939566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetConcatenate(*sumSpace, concatenate)); 594d092c84bSBrandon Whitchurch for (i = 0; i < numSubspaces; ++i) { 595d092c84bSBrandon Whitchurch PetscInt sNc; 596d092c84bSBrandon Whitchurch 5979566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetSubspace(*sumSpace, i, subspaces[i])); 5989566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(subspaces[i], &sNc)); 599d092c84bSBrandon Whitchurch if (concatenate) Nc += sNc; 600d092c84bSBrandon Whitchurch else Nc = sNc; 601d092c84bSBrandon Whitchurch } 6029566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(subspaces[0], &Nv)); 6039566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(*sumSpace, Nc)); 6049566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(*sumSpace, Nv)); 6059566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(*sumSpace)); 606d092c84bSBrandon Whitchurch 6073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 608d092c84bSBrandon Whitchurch } 609