1d092c84bSBrandon Whitchurch #include <petsc/private/petscfeimpl.h> /*I "petscfe.h" I*/ 2b24fb147SBarry Smith 3d092c84bSBrandon Whitchurch /*@ 4b24fb147SBarry 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 14b24fb147SBarry Smith Note: 15b24fb147SBarry 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 16b24fb147SBarry 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); 234f572ea9SToby Isaac PetscAssertPointer(numSumSpaces, 2); 24cac4c232SBarry Smith PetscTryMethod(sp, "PetscSpaceSumGetNumSubspaces_C", (PetscSpace, PetscInt *), (sp, numSumSpaces)); 253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26d092c84bSBrandon Whitchurch } 27d092c84bSBrandon Whitchurch 28d092c84bSBrandon Whitchurch /*@ 29b24fb147SBarry 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 37b24fb147SBarry Smith Note: 38b24fb147SBarry 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 39b24fb147SBarry 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 532fe279fdSBarry Smith Input Parameter: 54d092c84bSBrandon Whitchurch . sp - the function space object 55d092c84bSBrandon Whitchurch 562fe279fdSBarry Smith Output Parameter: 57d092c84bSBrandon Whitchurch . concatenate - flag indicating whether subspaces are concatenated. 58d092c84bSBrandon Whitchurch 59d092c84bSBrandon Whitchurch Level: intermediate 60d092c84bSBrandon Whitchurch 61*a4e35b19SJacob Faibussowitsch Notes: 62*a4e35b19SJacob Faibussowitsch A concatenated sum space will have the number of components equal to the sum of the number of 63*a4e35b19SJacob Faibussowitsch components of all subspaces. A non-concatenated, or direct sum space will have the same 64*a4e35b19SJacob Faibussowitsch number of components as its subspaces. 65*a4e35b19SJacob Faibussowitsch 66dce8aebaSBarry Smith .seealso: `PETSCSPACESUM`, `PetscSpace`, `PetscSpaceSumSetConcatenate()` 67d092c84bSBrandon Whitchurch @*/ 68d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSpaceSumGetConcatenate(PetscSpace sp, PetscBool *concatenate) 69d71ae5a4SJacob Faibussowitsch { 70d092c84bSBrandon Whitchurch PetscFunctionBegin; 71d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 72cac4c232SBarry Smith PetscTryMethod(sp, "PetscSpaceSumGetConcatenate_C", (PetscSpace, PetscBool *), (sp, concatenate)); 733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 74d092c84bSBrandon Whitchurch } 75d092c84bSBrandon Whitchurch 76d092c84bSBrandon Whitchurch /*@ 77d092c84bSBrandon Whitchurch PetscSpaceSumSetConcatenate - Sets the concatenate flag for this space. 78d092c84bSBrandon Whitchurch 79d092c84bSBrandon Whitchurch Input Parameters: 80d092c84bSBrandon Whitchurch + sp - the function space object 81d092c84bSBrandon Whitchurch - concatenate - are subspaces concatenated components (true) or direct summands (false) 82d092c84bSBrandon Whitchurch 83d092c84bSBrandon Whitchurch Level: intermediate 84dce8aebaSBarry Smith 85*a4e35b19SJacob Faibussowitsch Notes: 86*a4e35b19SJacob Faibussowitsch A concatenated sum space will have the number of components equal to the sum of the number of 87*a4e35b19SJacob Faibussowitsch components of all subspaces. A non-concatenated, or direct sum space will have the same 88*a4e35b19SJacob Faibussowitsch number of components as its subspaces . 89*a4e35b19SJacob Faibussowitsch 90dce8aebaSBarry Smith .seealso: `PETSCSPACESUM`, `PetscSpace`, `PetscSpaceSumGetConcatenate()` 91d092c84bSBrandon Whitchurch @*/ 92d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSpaceSumSetConcatenate(PetscSpace sp, PetscBool concatenate) 93d71ae5a4SJacob Faibussowitsch { 94d092c84bSBrandon Whitchurch PetscFunctionBegin; 95d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 96cac4c232SBarry Smith PetscTryMethod(sp, "PetscSpaceSumSetConcatenate_C", (PetscSpace, PetscBool), (sp, concatenate)); 973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 98d092c84bSBrandon Whitchurch } 99d092c84bSBrandon Whitchurch 100d092c84bSBrandon Whitchurch /*@ 101b24fb147SBarry Smith PetscSpaceSumGetSubspace - Get a space in the sum space 102d092c84bSBrandon Whitchurch 103d092c84bSBrandon Whitchurch Input Parameters: 104d092c84bSBrandon Whitchurch + sp - the function space object 105d092c84bSBrandon Whitchurch - s - The space number 106d092c84bSBrandon Whitchurch 107d092c84bSBrandon Whitchurch Output Parameter: 108b24fb147SBarry Smith . subsp - the `PetscSpace` 109d092c84bSBrandon Whitchurch 110d092c84bSBrandon Whitchurch Level: intermediate 111d092c84bSBrandon Whitchurch 112b24fb147SBarry Smith Note: 113b24fb147SBarry 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 114b24fb147SBarry Smith 115dce8aebaSBarry Smith .seealso: `PETSCSPACESUM`, `PetscSpace`, `PetscSpaceSumSetSubspace()`, `PetscSpaceSetDegree()`, `PetscSpaceSetNumVariables()` 116d092c84bSBrandon Whitchurch @*/ 117d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSpaceSumGetSubspace(PetscSpace sp, PetscInt s, PetscSpace *subsp) 118d71ae5a4SJacob Faibussowitsch { 119d092c84bSBrandon Whitchurch PetscFunctionBegin; 120d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 1214f572ea9SToby Isaac PetscAssertPointer(subsp, 3); 122cac4c232SBarry Smith PetscTryMethod(sp, "PetscSpaceSumGetSubspace_C", (PetscSpace, PetscInt, PetscSpace *), (sp, s, subsp)); 1233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 124d092c84bSBrandon Whitchurch } 125d092c84bSBrandon Whitchurch 126d092c84bSBrandon Whitchurch /*@ 127b24fb147SBarry Smith PetscSpaceSumSetSubspace - Set a space in the sum space 128d092c84bSBrandon Whitchurch 129d092c84bSBrandon Whitchurch Input Parameters: 130d092c84bSBrandon Whitchurch + sp - the function space object 131d092c84bSBrandon Whitchurch . s - The space number 132d092c84bSBrandon Whitchurch - subsp - the number of spaces 133d092c84bSBrandon Whitchurch 134d092c84bSBrandon Whitchurch Level: intermediate 135d092c84bSBrandon Whitchurch 136b24fb147SBarry Smith Note: 137b24fb147SBarry 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 138b24fb147SBarry Smith 139dce8aebaSBarry Smith .seealso: `PETSCSPACESUM`, `PetscSpace`, `PetscSpaceSumGetSubspace()`, `PetscSpaceSetDegree()`, `PetscSpaceSetNumVariables()` 140d092c84bSBrandon Whitchurch @*/ 141d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSpaceSumSetSubspace(PetscSpace sp, PetscInt s, PetscSpace subsp) 142d71ae5a4SJacob Faibussowitsch { 143d092c84bSBrandon Whitchurch PetscFunctionBegin; 144d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 145d092c84bSBrandon Whitchurch if (subsp) PetscValidHeaderSpecific(subsp, PETSCSPACE_CLASSID, 3); 146cac4c232SBarry Smith PetscTryMethod(sp, "PetscSpaceSumSetSubspace_C", (PetscSpace, PetscInt, PetscSpace), (sp, s, subsp)); 1473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 148d092c84bSBrandon Whitchurch } 149d092c84bSBrandon Whitchurch 150d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSumGetNumSubspaces_Sum(PetscSpace space, PetscInt *numSumSpaces) 151d71ae5a4SJacob Faibussowitsch { 152d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)space->data; 153d092c84bSBrandon Whitchurch 154d092c84bSBrandon Whitchurch PetscFunctionBegin; 155d092c84bSBrandon Whitchurch *numSumSpaces = sum->numSumSpaces; 1563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 157d092c84bSBrandon Whitchurch } 158d092c84bSBrandon Whitchurch 159d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSumSetNumSubspaces_Sum(PetscSpace space, PetscInt numSumSpaces) 160d71ae5a4SJacob Faibussowitsch { 161d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)space->data; 162d092c84bSBrandon Whitchurch PetscInt Ns = sum->numSumSpaces; 163d092c84bSBrandon Whitchurch 164d092c84bSBrandon Whitchurch PetscFunctionBegin; 16528b400f6SJacob Faibussowitsch PetscCheck(!sum->setupCalled, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_WRONGSTATE, "Cannot change number of subspaces after setup called"); 1663ba16761SJacob Faibussowitsch if (numSumSpaces == Ns) PetscFunctionReturn(PETSC_SUCCESS); 167d092c84bSBrandon Whitchurch if (Ns >= 0) { 168d092c84bSBrandon Whitchurch PetscInt s; 16948a46eb9SPierre Jolivet for (s = 0; s < Ns; ++s) PetscCall(PetscSpaceDestroy(&sum->sumspaces[s])); 1709566063dSJacob Faibussowitsch PetscCall(PetscFree(sum->sumspaces)); 171d092c84bSBrandon Whitchurch } 172d092c84bSBrandon Whitchurch 173d092c84bSBrandon Whitchurch Ns = sum->numSumSpaces = numSumSpaces; 1749566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Ns, &sum->sumspaces)); 1753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 176d092c84bSBrandon Whitchurch } 177d092c84bSBrandon Whitchurch 178d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSumGetConcatenate_Sum(PetscSpace sp, PetscBool *concatenate) 179d71ae5a4SJacob Faibussowitsch { 180d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 181d092c84bSBrandon Whitchurch 182d092c84bSBrandon Whitchurch PetscFunctionBegin; 183d092c84bSBrandon Whitchurch *concatenate = sum->concatenate; 1843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 185d092c84bSBrandon Whitchurch } 186d092c84bSBrandon Whitchurch 187d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSumSetConcatenate_Sum(PetscSpace sp, PetscBool concatenate) 188d71ae5a4SJacob Faibussowitsch { 189d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 190d092c84bSBrandon Whitchurch 191d092c84bSBrandon Whitchurch PetscFunctionBegin; 19228b400f6SJacob Faibussowitsch PetscCheck(!sum->setupCalled, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_WRONGSTATE, "Cannot change space concatenation after setup called."); 193d092c84bSBrandon Whitchurch 194d092c84bSBrandon Whitchurch sum->concatenate = concatenate; 1953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 196d092c84bSBrandon Whitchurch } 197d092c84bSBrandon Whitchurch 198d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSumGetSubspace_Sum(PetscSpace space, PetscInt s, PetscSpace *subspace) 199d71ae5a4SJacob Faibussowitsch { 200d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)space->data; 201d092c84bSBrandon Whitchurch PetscInt Ns = sum->numSumSpaces; 202d092c84bSBrandon Whitchurch 203d092c84bSBrandon Whitchurch PetscFunctionBegin; 20408401ef6SPierre Jolivet PetscCheck(Ns >= 0, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_WRONGSTATE, "Must call PetscSpaceSumSetNumSubspaces() first"); 2051dca8a05SBarry Smith PetscCheck(s >= 0 && s < Ns, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_OUTOFRANGE, "Invalid subspace number %" PetscInt_FMT, s); 206d092c84bSBrandon Whitchurch 207d092c84bSBrandon Whitchurch *subspace = sum->sumspaces[s]; 2083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 209d092c84bSBrandon Whitchurch } 210d092c84bSBrandon Whitchurch 211d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSumSetSubspace_Sum(PetscSpace space, PetscInt s, PetscSpace subspace) 212d71ae5a4SJacob Faibussowitsch { 213d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)space->data; 214d092c84bSBrandon Whitchurch PetscInt Ns = sum->numSumSpaces; 215d092c84bSBrandon Whitchurch 216d092c84bSBrandon Whitchurch PetscFunctionBegin; 21728b400f6SJacob Faibussowitsch PetscCheck(!sum->setupCalled, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_WRONGSTATE, "Cannot change subspace after setup called"); 21808401ef6SPierre Jolivet PetscCheck(Ns >= 0, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_WRONGSTATE, "Must call PetscSpaceSumSetNumSubspaces() first"); 2191dca8a05SBarry Smith PetscCheck(s >= 0 && s < Ns, PetscObjectComm((PetscObject)space), PETSC_ERR_ARG_OUTOFRANGE, "Invalid subspace number %" PetscInt_FMT, s); 220d092c84bSBrandon Whitchurch 2219566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)subspace)); 2229566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&sum->sumspaces[s])); 223d092c84bSBrandon Whitchurch sum->sumspaces[s] = subspace; 2243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 225d092c84bSBrandon Whitchurch } 226d092c84bSBrandon Whitchurch 227d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSetFromOptions_Sum(PetscSpace sp, PetscOptionItems *PetscOptionsObject) 228d71ae5a4SJacob Faibussowitsch { 229d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 230d092c84bSBrandon Whitchurch PetscInt Ns, Nc, Nv, deg, i; 231d092c84bSBrandon Whitchurch PetscBool concatenate = PETSC_TRUE; 232d092c84bSBrandon Whitchurch const char *prefix; 233d092c84bSBrandon Whitchurch 234d092c84bSBrandon Whitchurch PetscFunctionBegin; 2359566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sp, &Nv)); 2363ba16761SJacob Faibussowitsch if (!Nv) PetscFunctionReturn(PETSC_SUCCESS); 2379566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(sp, &Nc)); 2389566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumGetNumSubspaces(sp, &Ns)); 2399566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(sp, °, NULL)); 240d092c84bSBrandon Whitchurch Ns = (Ns == PETSC_DEFAULT) ? 1 : Ns; 241d092c84bSBrandon Whitchurch 242d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "PetscSpace sum options"); 2439566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-petscspace_sum_spaces", "The number of subspaces", "PetscSpaceSumSetNumSubspaces", Ns, &Ns, NULL, 0)); 2449371c9d4SSatish Balay PetscCall(PetscOptionsBool("-petscspace_sum_concatenate", "Subspaces are concatenated components of the final space", "PetscSpaceSumSetFromOptions", concatenate, &concatenate, NULL)); 245d0609cedSBarry Smith PetscOptionsHeadEnd(); 246d092c84bSBrandon Whitchurch 2471dca8a05SBarry 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); 24848a46eb9SPierre Jolivet if (Ns != sum->numSumSpaces) PetscCall(PetscSpaceSumSetNumSubspaces(sp, Ns)); 2499566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)sp, &prefix)); 250d092c84bSBrandon Whitchurch for (i = 0; i < Ns; ++i) { 251d092c84bSBrandon Whitchurch PetscInt sNv; 252d092c84bSBrandon Whitchurch PetscSpace subspace; 253d092c84bSBrandon Whitchurch 2549566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumGetSubspace(sp, i, &subspace)); 255d092c84bSBrandon Whitchurch if (!subspace) { 256d092c84bSBrandon Whitchurch char subspacePrefix[256]; 257d092c84bSBrandon Whitchurch 2589566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(PetscObjectComm((PetscObject)sp), &subspace)); 2599566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)subspace, prefix)); 26063a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(subspacePrefix, 256, "sumcomp_%" PetscInt_FMT "_", i)); 2619566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)subspace, subspacePrefix)); 2621baa6e33SBarry Smith } else PetscCall(PetscObjectReference((PetscObject)subspace)); 2639566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetFromOptions(subspace)); 2649566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(subspace, &sNv)); 26563a3b9bcSJacob Faibussowitsch PetscCheck(sNv, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_WRONGSTATE, "Subspace %" PetscInt_FMT " has not been set properly, number of variables is 0.", i); 2669566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetSubspace(sp, i, subspace)); 2679566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&subspace)); 268d092c84bSBrandon Whitchurch } 2693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 270d092c84bSBrandon Whitchurch } 271d092c84bSBrandon Whitchurch 272d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSetUp_Sum(PetscSpace sp) 273d71ae5a4SJacob Faibussowitsch { 274d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 275d092c84bSBrandon Whitchurch PetscBool concatenate = PETSC_TRUE; 276642c7897SToby Isaac PetscBool uniform; 277642c7897SToby Isaac PetscInt Nv, Ns, Nc, i, sum_Nc = 0, deg = PETSC_MAX_INT, maxDeg = PETSC_MIN_INT; 278642c7897SToby Isaac PetscInt minNc, maxNc; 279d092c84bSBrandon Whitchurch 280d092c84bSBrandon Whitchurch PetscFunctionBegin; 2813ba16761SJacob Faibussowitsch if (sum->setupCalled) PetscFunctionReturn(PETSC_SUCCESS); 282d092c84bSBrandon Whitchurch 2839566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sp, &Nv)); 2849566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(sp, &Nc)); 2859566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumGetNumSubspaces(sp, &Ns)); 286d092c84bSBrandon Whitchurch if (Ns == PETSC_DEFAULT) { 287d092c84bSBrandon Whitchurch Ns = 1; 2889566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetNumSubspaces(sp, Ns)); 289d092c84bSBrandon Whitchurch } 29063a3b9bcSJacob Faibussowitsch PetscCheck(Ns >= 0, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_OUTOFRANGE, "Cannot have %" PetscInt_FMT " subspaces", Ns); 291642c7897SToby Isaac uniform = PETSC_TRUE; 292642c7897SToby Isaac if (Ns) { 293642c7897SToby Isaac PetscSpace s0; 294d092c84bSBrandon Whitchurch 2959566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumGetSubspace(sp, 0, &s0)); 296642c7897SToby Isaac for (PetscInt i = 1; i < Ns; i++) { 297642c7897SToby Isaac PetscSpace si; 298642c7897SToby Isaac 2999566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumGetSubspace(sp, i, &si)); 300642c7897SToby Isaac if (si != s0) { 301642c7897SToby Isaac uniform = PETSC_FALSE; 302642c7897SToby Isaac break; 303642c7897SToby Isaac } 304642c7897SToby Isaac } 305642c7897SToby Isaac } 306642c7897SToby Isaac 307642c7897SToby Isaac minNc = Nc; 308642c7897SToby Isaac maxNc = Nc; 309d092c84bSBrandon Whitchurch for (i = 0; i < Ns; ++i) { 310d092c84bSBrandon Whitchurch PetscInt sNv, sNc, iDeg, iMaxDeg; 311d092c84bSBrandon Whitchurch PetscSpace si; 312d092c84bSBrandon Whitchurch 3139566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumGetSubspace(sp, i, &si)); 3149566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(si)); 3159566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(si, &sNv)); 31663a3b9bcSJacob 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); 3179566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(si, &sNc)); 318d092c84bSBrandon Whitchurch if (i == 0 && sNc == Nc) concatenate = PETSC_FALSE; 319642c7897SToby Isaac minNc = PetscMin(minNc, sNc); 320642c7897SToby Isaac maxNc = PetscMax(maxNc, sNc); 321d092c84bSBrandon Whitchurch sum_Nc += sNc; 3229566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumGetSubspace(sp, i, &si)); 3239566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(si, &iDeg, &iMaxDeg)); 324642c7897SToby Isaac deg = PetscMin(deg, iDeg); 325d092c84bSBrandon Whitchurch maxDeg = PetscMax(maxDeg, iMaxDeg); 326d092c84bSBrandon Whitchurch } 327d092c84bSBrandon Whitchurch 3287a46b595SBarry 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); 3297a46b595SBarry 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."); 330d092c84bSBrandon Whitchurch 331d092c84bSBrandon Whitchurch sp->degree = deg; 332d092c84bSBrandon Whitchurch sp->maxDegree = maxDeg; 333d092c84bSBrandon Whitchurch sum->concatenate = concatenate; 334642c7897SToby Isaac sum->uniform = uniform; 335d092c84bSBrandon Whitchurch sum->setupCalled = PETSC_TRUE; 3363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 337d092c84bSBrandon Whitchurch } 338d092c84bSBrandon Whitchurch 339d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceSumView_Ascii(PetscSpace sp, PetscViewer v) 340d71ae5a4SJacob Faibussowitsch { 341d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 342d092c84bSBrandon Whitchurch PetscBool concatenate = sum->concatenate; 343d092c84bSBrandon Whitchurch PetscInt i, Ns = sum->numSumSpaces; 344d092c84bSBrandon Whitchurch 345d092c84bSBrandon Whitchurch PetscFunctionBegin; 3461baa6e33SBarry Smith if (concatenate) PetscCall(PetscViewerASCIIPrintf(v, "Sum space of %" PetscInt_FMT " concatenated subspaces%s\n", Ns, sum->uniform ? " (all identical)" : "")); 3471baa6e33SBarry Smith else PetscCall(PetscViewerASCIIPrintf(v, "Sum space of %" PetscInt_FMT " subspaces%s\n", Ns, sum->uniform ? " (all identical)" : "")); 348642c7897SToby Isaac for (i = 0; i < (sum->uniform ? (Ns > 0 ? 1 : 0) : Ns); ++i) { 3499566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(v)); 3509566063dSJacob Faibussowitsch PetscCall(PetscSpaceView(sum->sumspaces[i], v)); 3519566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(v)); 352d092c84bSBrandon Whitchurch } 3533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 354d092c84bSBrandon Whitchurch } 355d092c84bSBrandon Whitchurch 356d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceView_Sum(PetscSpace sp, PetscViewer viewer) 357d71ae5a4SJacob Faibussowitsch { 358d092c84bSBrandon Whitchurch PetscBool iascii; 359d092c84bSBrandon Whitchurch 360d092c84bSBrandon Whitchurch PetscFunctionBegin; 3619566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 3621baa6e33SBarry Smith if (iascii) PetscCall(PetscSpaceSumView_Ascii(sp, viewer)); 3633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 364d092c84bSBrandon Whitchurch } 365d092c84bSBrandon Whitchurch 366d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceDestroy_Sum(PetscSpace sp) 367d71ae5a4SJacob Faibussowitsch { 368d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 369d092c84bSBrandon Whitchurch PetscInt i, Ns = sum->numSumSpaces; 370d092c84bSBrandon Whitchurch 371d092c84bSBrandon Whitchurch PetscFunctionBegin; 37248a46eb9SPierre Jolivet for (i = 0; i < Ns; ++i) PetscCall(PetscSpaceDestroy(&sum->sumspaces[i])); 3739566063dSJacob Faibussowitsch PetscCall(PetscFree(sum->sumspaces)); 374642c7897SToby Isaac if (sum->heightsubspaces) { 375642c7897SToby Isaac PetscInt d; 376642c7897SToby Isaac 377642c7897SToby Isaac /* sp->Nv is the spatial dimension, so it is equal to the number 378642c7897SToby Isaac * of subspaces on higher co-dimension points */ 37948a46eb9SPierre Jolivet for (d = 0; d < sp->Nv; ++d) PetscCall(PetscSpaceDestroy(&sum->heightsubspaces[d])); 380642c7897SToby Isaac } 3819566063dSJacob Faibussowitsch PetscCall(PetscFree(sum->heightsubspaces)); 3829566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetSubspace_C", NULL)); 3839566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetSubspace_C", NULL)); 3849566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetNumSubspaces_C", NULL)); 3859566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetNumSubspaces_C", NULL)); 3862e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetConcatenate_C", NULL)); 3872e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetConcatenate_C", NULL)); 3889566063dSJacob Faibussowitsch PetscCall(PetscFree(sum)); 3893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 390d092c84bSBrandon Whitchurch } 391d092c84bSBrandon Whitchurch 392d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceGetDimension_Sum(PetscSpace sp, PetscInt *dim) 393d71ae5a4SJacob Faibussowitsch { 394d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 395d092c84bSBrandon Whitchurch PetscInt i, d = 0, Ns = sum->numSumSpaces; 396d092c84bSBrandon Whitchurch 397d092c84bSBrandon Whitchurch PetscFunctionBegin; 398642c7897SToby Isaac if (!sum->setupCalled) { 3999566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sp)); 4009566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDimension(sp, dim)); 4013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 402642c7897SToby Isaac } 403d092c84bSBrandon Whitchurch 404d092c84bSBrandon Whitchurch for (i = 0; i < Ns; ++i) { 405d092c84bSBrandon Whitchurch PetscInt id; 406d092c84bSBrandon Whitchurch 4079566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDimension(sum->sumspaces[i], &id)); 408d092c84bSBrandon Whitchurch d += id; 409d092c84bSBrandon Whitchurch } 410d092c84bSBrandon Whitchurch 411d092c84bSBrandon Whitchurch *dim = d; 4123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 413d092c84bSBrandon Whitchurch } 414d092c84bSBrandon Whitchurch 415d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceEvaluate_Sum(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[]) 416d71ae5a4SJacob Faibussowitsch { 417d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 418d092c84bSBrandon Whitchurch PetscBool concatenate = sum->concatenate; 419d092c84bSBrandon Whitchurch DM dm = sp->dm; 420d092c84bSBrandon Whitchurch PetscInt Nc = sp->Nc, Nv = sp->Nv, Ns = sum->numSumSpaces; 421d092c84bSBrandon Whitchurch PetscInt i, s, offset, ncoffset, pdimfull, numelB, numelD, numelH; 422d092c84bSBrandon Whitchurch PetscReal *sB = NULL, *sD = NULL, *sH = NULL; 423d092c84bSBrandon Whitchurch 424d092c84bSBrandon Whitchurch PetscFunctionBegin; 425d092c84bSBrandon Whitchurch if (!sum->setupCalled) { 4269566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sp)); 4279566063dSJacob Faibussowitsch PetscCall(PetscSpaceEvaluate(sp, npoints, points, B, D, H)); 4283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 429d092c84bSBrandon Whitchurch } 4309566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDimension(sp, &pdimfull)); 431d092c84bSBrandon Whitchurch numelB = npoints * pdimfull * Nc; 432d092c84bSBrandon Whitchurch numelD = numelB * Nv; 433d092c84bSBrandon Whitchurch numelH = numelD * Nv; 43448a46eb9SPierre Jolivet if (B || D || H) PetscCall(DMGetWorkArray(dm, numelB, MPIU_REAL, &sB)); 43548a46eb9SPierre Jolivet if (D || H) PetscCall(DMGetWorkArray(dm, numelD, MPIU_REAL, &sD)); 43648a46eb9SPierre Jolivet if (H) PetscCall(DMGetWorkArray(dm, numelH, MPIU_REAL, &sH)); 437d092c84bSBrandon Whitchurch if (B) 438d092c84bSBrandon Whitchurch for (i = 0; i < numelB; ++i) B[i] = 0.; 439d092c84bSBrandon Whitchurch if (D) 440d092c84bSBrandon Whitchurch for (i = 0; i < numelD; ++i) D[i] = 0.; 441d092c84bSBrandon Whitchurch if (H) 442d092c84bSBrandon Whitchurch for (i = 0; i < numelH; ++i) H[i] = 0.; 443d092c84bSBrandon Whitchurch 444d092c84bSBrandon Whitchurch for (s = 0, offset = 0, ncoffset = 0; s < Ns; ++s) { 445d092c84bSBrandon Whitchurch PetscInt sNv, spdim, sNc, p; 446d092c84bSBrandon Whitchurch 4479566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sum->sumspaces[s], &sNv)); 4489566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(sum->sumspaces[s], &sNc)); 4499566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDimension(sum->sumspaces[s], &spdim)); 4501dca8a05SBarry Smith PetscCheck(offset + spdim <= pdimfull, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_OUTOFRANGE, "Subspace dimensions exceed target space dimension."); 45148a46eb9SPierre Jolivet if (s == 0 || !sum->uniform) PetscCall(PetscSpaceEvaluate(sum->sumspaces[s], npoints, points, sB, sD, sH)); 452d092c84bSBrandon Whitchurch if (B || D || H) { 453d092c84bSBrandon Whitchurch for (p = 0; p < npoints; ++p) { 454d092c84bSBrandon Whitchurch PetscInt j; 455d092c84bSBrandon Whitchurch 456d092c84bSBrandon Whitchurch for (j = 0; j < spdim; ++j) { 457d092c84bSBrandon Whitchurch PetscInt c; 458d092c84bSBrandon Whitchurch 459d092c84bSBrandon Whitchurch for (c = 0; c < sNc; ++c) { 460d092c84bSBrandon Whitchurch PetscInt compoffset, BInd, sBInd; 461d092c84bSBrandon Whitchurch 462d092c84bSBrandon Whitchurch compoffset = concatenate ? c + ncoffset : c; 463d092c84bSBrandon Whitchurch BInd = (p * pdimfull + j + offset) * Nc + compoffset; 464d092c84bSBrandon Whitchurch sBInd = (p * spdim + j) * sNc + c; 465642c7897SToby Isaac if (B) B[BInd] = sB[sBInd]; 466d092c84bSBrandon Whitchurch if (D || H) { 467d092c84bSBrandon Whitchurch PetscInt v; 468d092c84bSBrandon Whitchurch 469d092c84bSBrandon Whitchurch for (v = 0; v < Nv; ++v) { 470d092c84bSBrandon Whitchurch PetscInt DInd, sDInd; 471d092c84bSBrandon Whitchurch 472d092c84bSBrandon Whitchurch DInd = BInd * Nv + v; 473d092c84bSBrandon Whitchurch sDInd = sBInd * Nv + v; 474642c7897SToby Isaac if (D) D[DInd] = sD[sDInd]; 475d092c84bSBrandon Whitchurch if (H) { 476d092c84bSBrandon Whitchurch PetscInt v2; 477d092c84bSBrandon Whitchurch 478d092c84bSBrandon Whitchurch for (v2 = 0; v2 < Nv; ++v2) { 479d092c84bSBrandon Whitchurch PetscInt HInd, sHInd; 480d092c84bSBrandon Whitchurch 481d092c84bSBrandon Whitchurch HInd = DInd * Nv + v2; 482d092c84bSBrandon Whitchurch sHInd = sDInd * Nv + v2; 483642c7897SToby Isaac H[HInd] = sH[sHInd]; 484d092c84bSBrandon Whitchurch } 485d092c84bSBrandon Whitchurch } 486d092c84bSBrandon Whitchurch } 487d092c84bSBrandon Whitchurch } 488d092c84bSBrandon Whitchurch } 489d092c84bSBrandon Whitchurch } 490d092c84bSBrandon Whitchurch } 491d092c84bSBrandon Whitchurch } 492d092c84bSBrandon Whitchurch offset += spdim; 493d092c84bSBrandon Whitchurch ncoffset += sNc; 494d092c84bSBrandon Whitchurch } 495d092c84bSBrandon Whitchurch 49648a46eb9SPierre Jolivet if (H) PetscCall(DMRestoreWorkArray(dm, numelH, MPIU_REAL, &sH)); 49748a46eb9SPierre Jolivet if (D || H) PetscCall(DMRestoreWorkArray(dm, numelD, MPIU_REAL, &sD)); 49848a46eb9SPierre Jolivet if (B || D || H) PetscCall(DMRestoreWorkArray(dm, numelB, MPIU_REAL, &sB)); 4993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 500d092c84bSBrandon Whitchurch } 501d092c84bSBrandon Whitchurch 502d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceGetHeightSubspace_Sum(PetscSpace sp, PetscInt height, PetscSpace *subsp) 503d71ae5a4SJacob Faibussowitsch { 504642c7897SToby Isaac PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 505642c7897SToby Isaac PetscInt Nc, dim, order; 506642c7897SToby Isaac PetscBool tensor; 507642c7897SToby Isaac 508642c7897SToby Isaac PetscFunctionBegin; 5099566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(sp, &Nc)); 5109566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sp, &dim)); 5119566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(sp, &order, NULL)); 5129566063dSJacob Faibussowitsch PetscCall(PetscSpacePolynomialGetTensor(sp, &tensor)); 5131dca8a05SBarry 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); 5149566063dSJacob Faibussowitsch if (!sum->heightsubspaces) PetscCall(PetscCalloc1(dim, &sum->heightsubspaces)); 515642c7897SToby Isaac if (height <= dim) { 516642c7897SToby Isaac if (!sum->heightsubspaces[height - 1]) { 517642c7897SToby Isaac PetscSpace sub; 518642c7897SToby Isaac const char *name; 519642c7897SToby Isaac 5209566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(PetscObjectComm((PetscObject)sp), &sub)); 5219566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sp, &name)); 5229566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)sub, name)); 5239566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(sub, PETSCSPACESUM)); 5249566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetNumSubspaces(sub, sum->numSumSpaces)); 5259566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetConcatenate(sub, sum->concatenate)); 5269566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(sub, Nc)); 5279566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(sub, dim - height)); 528642c7897SToby Isaac for (PetscInt i = 0; i < sum->numSumSpaces; i++) { 529642c7897SToby Isaac PetscSpace subh; 530642c7897SToby Isaac 5319566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetHeightSubspace(sum->sumspaces[i], height, &subh)); 5329566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetSubspace(sub, i, subh)); 533642c7897SToby Isaac } 5349566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sub)); 535642c7897SToby Isaac sum->heightsubspaces[height - 1] = sub; 536642c7897SToby Isaac } 537642c7897SToby Isaac *subsp = sum->heightsubspaces[height - 1]; 538642c7897SToby Isaac } else { 539642c7897SToby Isaac *subsp = NULL; 540642c7897SToby Isaac } 5413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 542642c7897SToby Isaac } 543642c7897SToby Isaac 544d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceInitialize_Sum(PetscSpace sp) 545d71ae5a4SJacob Faibussowitsch { 546d092c84bSBrandon Whitchurch PetscFunctionBegin; 547d092c84bSBrandon Whitchurch sp->ops->setfromoptions = PetscSpaceSetFromOptions_Sum; 548d092c84bSBrandon Whitchurch sp->ops->setup = PetscSpaceSetUp_Sum; 549d092c84bSBrandon Whitchurch sp->ops->view = PetscSpaceView_Sum; 550d092c84bSBrandon Whitchurch sp->ops->destroy = PetscSpaceDestroy_Sum; 551d092c84bSBrandon Whitchurch sp->ops->getdimension = PetscSpaceGetDimension_Sum; 552d092c84bSBrandon Whitchurch sp->ops->evaluate = PetscSpaceEvaluate_Sum; 553642c7897SToby Isaac sp->ops->getheightsubspace = PetscSpaceGetHeightSubspace_Sum; 554d092c84bSBrandon Whitchurch 5559566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetNumSubspaces_C", PetscSpaceSumGetNumSubspaces_Sum)); 5569566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetNumSubspaces_C", PetscSpaceSumSetNumSubspaces_Sum)); 5579566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetSubspace_C", PetscSpaceSumGetSubspace_Sum)); 5589566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetSubspace_C", PetscSpaceSumSetSubspace_Sum)); 5599566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetConcatenate_C", PetscSpaceSumGetConcatenate_Sum)); 5609566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetConcatenate_C", PetscSpaceSumSetConcatenate_Sum)); 5613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 562d092c84bSBrandon Whitchurch } 563d092c84bSBrandon Whitchurch 564d092c84bSBrandon Whitchurch /*MC 565dce8aebaSBarry Smith PETSCSPACESUM = "sum" - A `PetscSpace` object that encapsulates a sum of subspaces. 566d092c84bSBrandon Whitchurch 567d092c84bSBrandon Whitchurch Level: intermediate 568d092c84bSBrandon Whitchurch 569b24fb147SBarry Smith Note: 570b24fb147SBarry Smith That sum can either be direct or a concatenation. For example if A and B are spaces each with 2 components, 571b24fb147SBarry 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 572b24fb147SBarry Smith same number of variables. 573b24fb147SBarry Smith 574b24fb147SBarry Smith .seealso: `PetscSpace`, `PetscSpaceType`, `PetscSpaceCreate()`, `PetscSpaceSetType()`, `PetscSpaceSumGetNumSubspaces()`, `PetscSpaceSumSetNumSubspaces()`, 575b24fb147SBarry Smith `PetscSpaceSumGetConcatenate()`, `PetscSpaceSumSetConcatenate()` 576d092c84bSBrandon Whitchurch M*/ 577d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscSpaceCreate_Sum(PetscSpace sp) 578d71ae5a4SJacob Faibussowitsch { 579d092c84bSBrandon Whitchurch PetscSpace_Sum *sum; 580d092c84bSBrandon Whitchurch 581d092c84bSBrandon Whitchurch PetscFunctionBegin; 582d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 5834dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&sum)); 584642c7897SToby Isaac sum->numSumSpaces = PETSC_DEFAULT; 585d092c84bSBrandon Whitchurch sp->data = sum; 5869566063dSJacob Faibussowitsch PetscCall(PetscSpaceInitialize_Sum(sp)); 5873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 588d092c84bSBrandon Whitchurch } 589d092c84bSBrandon Whitchurch 590d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscSpaceCreateSum(PetscInt numSubspaces, const PetscSpace subspaces[], PetscBool concatenate, PetscSpace *sumSpace) 591d71ae5a4SJacob Faibussowitsch { 592d092c84bSBrandon Whitchurch PetscInt i, Nv, Nc = 0; 593d092c84bSBrandon Whitchurch 594d092c84bSBrandon Whitchurch PetscFunctionBegin; 5951baa6e33SBarry Smith if (sumSpace) PetscCall(PetscSpaceDestroy(sumSpace)); 5969566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(PetscObjectComm((PetscObject)subspaces[0]), sumSpace)); 5979566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(*sumSpace, PETSCSPACESUM)); 5989566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetNumSubspaces(*sumSpace, numSubspaces)); 5999566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetConcatenate(*sumSpace, concatenate)); 600d092c84bSBrandon Whitchurch for (i = 0; i < numSubspaces; ++i) { 601d092c84bSBrandon Whitchurch PetscInt sNc; 602d092c84bSBrandon Whitchurch 6039566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetSubspace(*sumSpace, i, subspaces[i])); 6049566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(subspaces[i], &sNc)); 605d092c84bSBrandon Whitchurch if (concatenate) Nc += sNc; 606d092c84bSBrandon Whitchurch else Nc = sNc; 607d092c84bSBrandon Whitchurch } 6089566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(subspaces[0], &Nv)); 6099566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(*sumSpace, Nc)); 6109566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(*sumSpace, Nv)); 6119566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(*sumSpace)); 612d092c84bSBrandon Whitchurch 6133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 614d092c84bSBrandon Whitchurch } 615