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 61a4e35b19SJacob Faibussowitsch Notes: 62a4e35b19SJacob Faibussowitsch A concatenated sum space will have the number of components equal to the sum of the number of 63a4e35b19SJacob Faibussowitsch components of all subspaces. A non-concatenated, or direct sum space will have the same 64a4e35b19SJacob Faibussowitsch number of components as its subspaces. 65a4e35b19SJacob 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 85a4e35b19SJacob Faibussowitsch Notes: 86a4e35b19SJacob Faibussowitsch A concatenated sum space will have the number of components equal to the sum of the number of 87a4e35b19SJacob Faibussowitsch components of all subspaces. A non-concatenated, or direct sum space will have the same 88a4e35b19SJacob Faibussowitsch number of components as its subspaces . 89a4e35b19SJacob 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)); 3882dce792eSToby Isaac PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetInterleave_C", NULL)); 3892dce792eSToby Isaac PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetInterleave_C", NULL)); 3909566063dSJacob Faibussowitsch PetscCall(PetscFree(sum)); 3913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 392d092c84bSBrandon Whitchurch } 393d092c84bSBrandon Whitchurch 394d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceGetDimension_Sum(PetscSpace sp, PetscInt *dim) 395d71ae5a4SJacob Faibussowitsch { 396d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 397d092c84bSBrandon Whitchurch PetscInt i, d = 0, Ns = sum->numSumSpaces; 398d092c84bSBrandon Whitchurch 399d092c84bSBrandon Whitchurch PetscFunctionBegin; 400642c7897SToby Isaac if (!sum->setupCalled) { 4019566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sp)); 4029566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDimension(sp, dim)); 4033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 404642c7897SToby Isaac } 405d092c84bSBrandon Whitchurch 406d092c84bSBrandon Whitchurch for (i = 0; i < Ns; ++i) { 407d092c84bSBrandon Whitchurch PetscInt id; 408d092c84bSBrandon Whitchurch 4099566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDimension(sum->sumspaces[i], &id)); 410d092c84bSBrandon Whitchurch d += id; 411d092c84bSBrandon Whitchurch } 412d092c84bSBrandon Whitchurch 413d092c84bSBrandon Whitchurch *dim = d; 4143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 415d092c84bSBrandon Whitchurch } 416d092c84bSBrandon Whitchurch 417d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceEvaluate_Sum(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[]) 418d71ae5a4SJacob Faibussowitsch { 419d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 420d092c84bSBrandon Whitchurch PetscBool concatenate = sum->concatenate; 421d092c84bSBrandon Whitchurch DM dm = sp->dm; 422d092c84bSBrandon Whitchurch PetscInt Nc = sp->Nc, Nv = sp->Nv, Ns = sum->numSumSpaces; 423d092c84bSBrandon Whitchurch PetscInt i, s, offset, ncoffset, pdimfull, numelB, numelD, numelH; 424d092c84bSBrandon Whitchurch PetscReal *sB = NULL, *sD = NULL, *sH = NULL; 425d092c84bSBrandon Whitchurch 426d092c84bSBrandon Whitchurch PetscFunctionBegin; 427d092c84bSBrandon Whitchurch if (!sum->setupCalled) { 4289566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sp)); 4299566063dSJacob Faibussowitsch PetscCall(PetscSpaceEvaluate(sp, npoints, points, B, D, H)); 4303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 431d092c84bSBrandon Whitchurch } 4329566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDimension(sp, &pdimfull)); 433d092c84bSBrandon Whitchurch numelB = npoints * pdimfull * Nc; 434d092c84bSBrandon Whitchurch numelD = numelB * Nv; 435d092c84bSBrandon Whitchurch numelH = numelD * Nv; 43648a46eb9SPierre Jolivet if (B || D || H) PetscCall(DMGetWorkArray(dm, numelB, MPIU_REAL, &sB)); 43748a46eb9SPierre Jolivet if (D || H) PetscCall(DMGetWorkArray(dm, numelD, MPIU_REAL, &sD)); 43848a46eb9SPierre Jolivet if (H) PetscCall(DMGetWorkArray(dm, numelH, MPIU_REAL, &sH)); 439d092c84bSBrandon Whitchurch if (B) 440d092c84bSBrandon Whitchurch for (i = 0; i < numelB; ++i) B[i] = 0.; 441d092c84bSBrandon Whitchurch if (D) 442d092c84bSBrandon Whitchurch for (i = 0; i < numelD; ++i) D[i] = 0.; 443d092c84bSBrandon Whitchurch if (H) 444d092c84bSBrandon Whitchurch for (i = 0; i < numelH; ++i) H[i] = 0.; 445d092c84bSBrandon Whitchurch 446d092c84bSBrandon Whitchurch for (s = 0, offset = 0, ncoffset = 0; s < Ns; ++s) { 447d092c84bSBrandon Whitchurch PetscInt sNv, spdim, sNc, p; 448d092c84bSBrandon Whitchurch 4499566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sum->sumspaces[s], &sNv)); 4509566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(sum->sumspaces[s], &sNc)); 4519566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDimension(sum->sumspaces[s], &spdim)); 4521dca8a05SBarry Smith PetscCheck(offset + spdim <= pdimfull, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_OUTOFRANGE, "Subspace dimensions exceed target space dimension."); 45348a46eb9SPierre Jolivet if (s == 0 || !sum->uniform) PetscCall(PetscSpaceEvaluate(sum->sumspaces[s], npoints, points, sB, sD, sH)); 454d092c84bSBrandon Whitchurch if (B || D || H) { 455d092c84bSBrandon Whitchurch for (p = 0; p < npoints; ++p) { 456d092c84bSBrandon Whitchurch PetscInt j; 457d092c84bSBrandon Whitchurch 458d092c84bSBrandon Whitchurch for (j = 0; j < spdim; ++j) { 459d092c84bSBrandon Whitchurch PetscInt c; 4602dce792eSToby Isaac PetscInt b = sum->interleave_basis ? (j * Ns + s) : (j + offset); 461d092c84bSBrandon Whitchurch 462d092c84bSBrandon Whitchurch for (c = 0; c < sNc; ++c) { 463d092c84bSBrandon Whitchurch PetscInt compoffset, BInd, sBInd; 464d092c84bSBrandon Whitchurch 4652dce792eSToby Isaac compoffset = concatenate ? (sum->interleave_components ? (c * Ns + s) : (c + ncoffset)) : c; 4662dce792eSToby Isaac BInd = (p * pdimfull + b) * Nc + compoffset; 467d092c84bSBrandon Whitchurch sBInd = (p * spdim + j) * sNc + c; 468642c7897SToby Isaac if (B) B[BInd] = sB[sBInd]; 469d092c84bSBrandon Whitchurch if (D || H) { 470d092c84bSBrandon Whitchurch PetscInt v; 471d092c84bSBrandon Whitchurch 472d092c84bSBrandon Whitchurch for (v = 0; v < Nv; ++v) { 473d092c84bSBrandon Whitchurch PetscInt DInd, sDInd; 474d092c84bSBrandon Whitchurch 475d092c84bSBrandon Whitchurch DInd = BInd * Nv + v; 476d092c84bSBrandon Whitchurch sDInd = sBInd * Nv + v; 477642c7897SToby Isaac if (D) D[DInd] = sD[sDInd]; 478d092c84bSBrandon Whitchurch if (H) { 479d092c84bSBrandon Whitchurch PetscInt v2; 480d092c84bSBrandon Whitchurch 481d092c84bSBrandon Whitchurch for (v2 = 0; v2 < Nv; ++v2) { 482d092c84bSBrandon Whitchurch PetscInt HInd, sHInd; 483d092c84bSBrandon Whitchurch 484d092c84bSBrandon Whitchurch HInd = DInd * Nv + v2; 485d092c84bSBrandon Whitchurch sHInd = sDInd * Nv + v2; 486642c7897SToby Isaac H[HInd] = sH[sHInd]; 487d092c84bSBrandon Whitchurch } 488d092c84bSBrandon Whitchurch } 489d092c84bSBrandon Whitchurch } 490d092c84bSBrandon Whitchurch } 491d092c84bSBrandon Whitchurch } 492d092c84bSBrandon Whitchurch } 493d092c84bSBrandon Whitchurch } 494d092c84bSBrandon Whitchurch } 495d092c84bSBrandon Whitchurch offset += spdim; 496d092c84bSBrandon Whitchurch ncoffset += sNc; 497d092c84bSBrandon Whitchurch } 498d092c84bSBrandon Whitchurch 49948a46eb9SPierre Jolivet if (H) PetscCall(DMRestoreWorkArray(dm, numelH, MPIU_REAL, &sH)); 50048a46eb9SPierre Jolivet if (D || H) PetscCall(DMRestoreWorkArray(dm, numelD, MPIU_REAL, &sD)); 50148a46eb9SPierre Jolivet if (B || D || H) PetscCall(DMRestoreWorkArray(dm, numelB, MPIU_REAL, &sB)); 5023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 503d092c84bSBrandon Whitchurch } 504d092c84bSBrandon Whitchurch 505d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceGetHeightSubspace_Sum(PetscSpace sp, PetscInt height, PetscSpace *subsp) 506d71ae5a4SJacob Faibussowitsch { 507642c7897SToby Isaac PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 508642c7897SToby Isaac PetscInt Nc, dim, order; 509642c7897SToby Isaac PetscBool tensor; 510642c7897SToby Isaac 511642c7897SToby Isaac PetscFunctionBegin; 5129566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(sp, &Nc)); 5139566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(sp, &dim)); 5149566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(sp, &order, NULL)); 5159566063dSJacob Faibussowitsch PetscCall(PetscSpacePolynomialGetTensor(sp, &tensor)); 5161dca8a05SBarry 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); 5179566063dSJacob Faibussowitsch if (!sum->heightsubspaces) PetscCall(PetscCalloc1(dim, &sum->heightsubspaces)); 518642c7897SToby Isaac if (height <= dim) { 519642c7897SToby Isaac if (!sum->heightsubspaces[height - 1]) { 520642c7897SToby Isaac PetscSpace sub; 521642c7897SToby Isaac const char *name; 522642c7897SToby Isaac 5239566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(PetscObjectComm((PetscObject)sp), &sub)); 5249566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sp, &name)); 5259566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)sub, name)); 5269566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(sub, PETSCSPACESUM)); 5279566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetNumSubspaces(sub, sum->numSumSpaces)); 5289566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetConcatenate(sub, sum->concatenate)); 5299566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(sub, Nc)); 5309566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(sub, dim - height)); 531642c7897SToby Isaac for (PetscInt i = 0; i < sum->numSumSpaces; i++) { 532642c7897SToby Isaac PetscSpace subh; 533642c7897SToby Isaac 5349566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetHeightSubspace(sum->sumspaces[i], height, &subh)); 5359566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetSubspace(sub, i, subh)); 536642c7897SToby Isaac } 5379566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(sub)); 538642c7897SToby Isaac sum->heightsubspaces[height - 1] = sub; 539642c7897SToby Isaac } 540642c7897SToby Isaac *subsp = sum->heightsubspaces[height - 1]; 541642c7897SToby Isaac } else { 542642c7897SToby Isaac *subsp = NULL; 543642c7897SToby Isaac } 5443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 545642c7897SToby Isaac } 546642c7897SToby Isaac 5472dce792eSToby Isaac /*@ 5482dce792eSToby Isaac PetscSpaceSumSetInterleave - Set whether the basis functions and components of a uniform sum are interleaved 5492dce792eSToby Isaac 5502dce792eSToby Isaac Logically collective 5512dce792eSToby Isaac 5522dce792eSToby Isaac Input Parameters: 5532dce792eSToby Isaac + sp - a `PetscSpace` of type `PETSCSPACESUM` 5542dce792eSToby Isaac . interleave_basis - if `PETSC_TRUE`, the basis vectors of the subspaces are interleaved 5552dce792eSToby Isaac - interleave_components - if `PETSC_TRUE` and the space concatenates components (`PetscSpaceSumGetConcatenate()`), 5562dce792eSToby Isaac interleave the concatenated components 5572dce792eSToby Isaac 5582dce792eSToby Isaac Level: developer 5592dce792eSToby Isaac 5602dce792eSToby Isaac .seealso: `PetscSpace`, `PETSCSPACESUM`, `PETSCFEVECTOR`, `PetscSpaceSumGetInterleave()` 5612dce792eSToby Isaac @*/ 5622dce792eSToby Isaac PetscErrorCode PetscSpaceSumSetInterleave(PetscSpace sp, PetscBool interleave_basis, PetscBool interleave_components) 5632dce792eSToby Isaac { 5642dce792eSToby Isaac PetscFunctionBegin; 5652dce792eSToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 5662dce792eSToby Isaac PetscTryMethod(sp, "PetscSpaceSumSetInterleave_C", (PetscSpace, PetscBool, PetscBool), (sp, interleave_basis, interleave_components)); 5672dce792eSToby Isaac PetscFunctionReturn(PETSC_SUCCESS); 5682dce792eSToby Isaac } 5692dce792eSToby Isaac 5702dce792eSToby Isaac static PetscErrorCode PetscSpaceSumSetInterleave_Sum(PetscSpace sp, PetscBool interleave_basis, PetscBool interleave_components) 5712dce792eSToby Isaac { 5722dce792eSToby Isaac PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 573*4d86920dSPierre Jolivet 5742dce792eSToby Isaac PetscFunctionBegin; 5752dce792eSToby Isaac sum->interleave_basis = interleave_basis; 5762dce792eSToby Isaac sum->interleave_components = interleave_components; 5772dce792eSToby Isaac PetscFunctionReturn(PETSC_SUCCESS); 5782dce792eSToby Isaac } 5792dce792eSToby Isaac 5802dce792eSToby Isaac /*@ 5812dce792eSToby Isaac PetscSpaceSumGetInterleave - Get whether the basis functions and components of a uniform sum are interleaved 5822dce792eSToby Isaac 5832dce792eSToby Isaac Logically collective 5842dce792eSToby Isaac 5852dce792eSToby Isaac Input Parameter: 5862dce792eSToby Isaac . sp - a `PetscSpace` of type `PETSCSPACESUM` 5872dce792eSToby Isaac 5882dce792eSToby Isaac Output Parameters: 5892dce792eSToby Isaac + interleave_basis - if `PETSC_TRUE`, the basis vectors of the subspaces are interleaved 5902dce792eSToby Isaac - interleave_components - if `PETSC_TRUE` and the space concatenates components (`PetscSpaceSumGetConcatenate()`), 5912dce792eSToby Isaac interleave the concatenated components 5922dce792eSToby Isaac 5932dce792eSToby Isaac Level: developer 5942dce792eSToby Isaac 5952dce792eSToby Isaac .seealso: `PetscSpace`, `PETSCSPACESUM`, `PETSCFEVECTOR`, `PetscSpaceSumSetInterleave()` 5962dce792eSToby Isaac @*/ 5972dce792eSToby Isaac PetscErrorCode PetscSpaceSumGetInterleave(PetscSpace sp, PetscBool *interleave_basis, PetscBool *interleave_components) 5982dce792eSToby Isaac { 5992dce792eSToby Isaac PetscFunctionBegin; 6002dce792eSToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 6012dce792eSToby Isaac if (interleave_basis) PetscAssertPointer(interleave_basis, 2); 6022dce792eSToby Isaac if (interleave_components) PetscAssertPointer(interleave_components, 3); 6032dce792eSToby Isaac PetscTryMethod(sp, "PetscSpaceSumGetInterleave_C", (PetscSpace, PetscBool *, PetscBool *), (sp, interleave_basis, interleave_components)); 6042dce792eSToby Isaac PetscFunctionReturn(PETSC_SUCCESS); 6052dce792eSToby Isaac } 6062dce792eSToby Isaac 6072dce792eSToby Isaac static PetscErrorCode PetscSpaceSumGetInterleave_Sum(PetscSpace sp, PetscBool *interleave_basis, PetscBool *interleave_components) 6082dce792eSToby Isaac { 6092dce792eSToby Isaac PetscSpace_Sum *sum = (PetscSpace_Sum *)sp->data; 610*4d86920dSPierre Jolivet 6112dce792eSToby Isaac PetscFunctionBegin; 6122dce792eSToby Isaac if (interleave_basis) *interleave_basis = sum->interleave_basis; 6132dce792eSToby Isaac if (interleave_components) *interleave_components = sum->interleave_components; 6142dce792eSToby Isaac PetscFunctionReturn(PETSC_SUCCESS); 6152dce792eSToby Isaac } 6162dce792eSToby Isaac 617d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSpaceInitialize_Sum(PetscSpace sp) 618d71ae5a4SJacob Faibussowitsch { 619d092c84bSBrandon Whitchurch PetscFunctionBegin; 620d092c84bSBrandon Whitchurch sp->ops->setfromoptions = PetscSpaceSetFromOptions_Sum; 621d092c84bSBrandon Whitchurch sp->ops->setup = PetscSpaceSetUp_Sum; 622d092c84bSBrandon Whitchurch sp->ops->view = PetscSpaceView_Sum; 623d092c84bSBrandon Whitchurch sp->ops->destroy = PetscSpaceDestroy_Sum; 624d092c84bSBrandon Whitchurch sp->ops->getdimension = PetscSpaceGetDimension_Sum; 625d092c84bSBrandon Whitchurch sp->ops->evaluate = PetscSpaceEvaluate_Sum; 626642c7897SToby Isaac sp->ops->getheightsubspace = PetscSpaceGetHeightSubspace_Sum; 627d092c84bSBrandon Whitchurch 6289566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetNumSubspaces_C", PetscSpaceSumGetNumSubspaces_Sum)); 6299566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetNumSubspaces_C", PetscSpaceSumSetNumSubspaces_Sum)); 6309566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetSubspace_C", PetscSpaceSumGetSubspace_Sum)); 6319566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetSubspace_C", PetscSpaceSumSetSubspace_Sum)); 6329566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetConcatenate_C", PetscSpaceSumGetConcatenate_Sum)); 6339566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetConcatenate_C", PetscSpaceSumSetConcatenate_Sum)); 6342dce792eSToby Isaac PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumGetInterleave_C", PetscSpaceSumGetInterleave_Sum)); 6352dce792eSToby Isaac PetscCall(PetscObjectComposeFunction((PetscObject)sp, "PetscSpaceSumSetInterleave_C", PetscSpaceSumSetInterleave_Sum)); 6363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 637d092c84bSBrandon Whitchurch } 638d092c84bSBrandon Whitchurch 639d092c84bSBrandon Whitchurch /*MC 640dce8aebaSBarry Smith PETSCSPACESUM = "sum" - A `PetscSpace` object that encapsulates a sum of subspaces. 641d092c84bSBrandon Whitchurch 642d092c84bSBrandon Whitchurch Level: intermediate 643d092c84bSBrandon Whitchurch 644b24fb147SBarry Smith Note: 645b24fb147SBarry Smith That sum can either be direct or a concatenation. For example if A and B are spaces each with 2 components, 646b24fb147SBarry 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 647b24fb147SBarry Smith same number of variables. 648b24fb147SBarry Smith 649b24fb147SBarry Smith .seealso: `PetscSpace`, `PetscSpaceType`, `PetscSpaceCreate()`, `PetscSpaceSetType()`, `PetscSpaceSumGetNumSubspaces()`, `PetscSpaceSumSetNumSubspaces()`, 650b24fb147SBarry Smith `PetscSpaceSumGetConcatenate()`, `PetscSpaceSumSetConcatenate()` 651d092c84bSBrandon Whitchurch M*/ 652d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscSpaceCreate_Sum(PetscSpace sp) 653d71ae5a4SJacob Faibussowitsch { 654d092c84bSBrandon Whitchurch PetscSpace_Sum *sum; 655d092c84bSBrandon Whitchurch 656d092c84bSBrandon Whitchurch PetscFunctionBegin; 657d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 6584dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&sum)); 659642c7897SToby Isaac sum->numSumSpaces = PETSC_DEFAULT; 660d092c84bSBrandon Whitchurch sp->data = sum; 6619566063dSJacob Faibussowitsch PetscCall(PetscSpaceInitialize_Sum(sp)); 6623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 663d092c84bSBrandon Whitchurch } 664d092c84bSBrandon Whitchurch 665d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscSpaceCreateSum(PetscInt numSubspaces, const PetscSpace subspaces[], PetscBool concatenate, PetscSpace *sumSpace) 666d71ae5a4SJacob Faibussowitsch { 667d092c84bSBrandon Whitchurch PetscInt i, Nv, Nc = 0; 668d092c84bSBrandon Whitchurch 669d092c84bSBrandon Whitchurch PetscFunctionBegin; 6709566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(PetscObjectComm((PetscObject)subspaces[0]), sumSpace)); 6719566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(*sumSpace, PETSCSPACESUM)); 6729566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetNumSubspaces(*sumSpace, numSubspaces)); 6739566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetConcatenate(*sumSpace, concatenate)); 674d092c84bSBrandon Whitchurch for (i = 0; i < numSubspaces; ++i) { 675d092c84bSBrandon Whitchurch PetscInt sNc; 676d092c84bSBrandon Whitchurch 6779566063dSJacob Faibussowitsch PetscCall(PetscSpaceSumSetSubspace(*sumSpace, i, subspaces[i])); 6789566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(subspaces[i], &sNc)); 679d092c84bSBrandon Whitchurch if (concatenate) Nc += sNc; 680d092c84bSBrandon Whitchurch else Nc = sNc; 681d092c84bSBrandon Whitchurch } 6829566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumVariables(subspaces[0], &Nv)); 6839566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(*sumSpace, Nc)); 6849566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(*sumSpace, Nv)); 6859566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(*sumSpace)); 6863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 687d092c84bSBrandon Whitchurch } 688