1d092c84bSBrandon Whitchurch #include <petsc/private/petscfeimpl.h> /*I "petscfe.h" I*/ 2d092c84bSBrandon Whitchurch /*@ 3d092c84bSBrandon Whitchurch PetscSpaceSumGetNumSubspaces - Get the number of spaces in the sum 4d092c84bSBrandon Whitchurch 5d092c84bSBrandon Whitchurch Input Parameter: 6d092c84bSBrandon Whitchurch . sp - the function space object 7d092c84bSBrandon Whitchurch 8d092c84bSBrandon Whitchurch Output Parameter: 9d092c84bSBrandon Whitchurch . numSumSpaces - the number of spaces 10d092c84bSBrandon Whitchurch 11d092c84bSBrandon Whitchurch Level: intermediate 12d092c84bSBrandon Whitchurch 13d092c84bSBrandon Whitchurch .seealso: PetscSpaceSumSetNumSubspaces(), PetscSpaceSetDegree(), PetscSpaceSetNumVariables() 14d092c84bSBrandon Whitchurch @*/ 15d092c84bSBrandon Whitchurch PetscErrorCode PetscSpaceSumGetNumSubspaces(PetscSpace sp,PetscInt *numSumSpaces) 16d092c84bSBrandon Whitchurch { 17d092c84bSBrandon Whitchurch PetscErrorCode ierr; 18d092c84bSBrandon Whitchurch 19d092c84bSBrandon Whitchurch PetscFunctionBegin; 20d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1); 21d092c84bSBrandon Whitchurch PetscValidIntPointer(numSumSpaces,2); 22d092c84bSBrandon Whitchurch ierr = PetscTryMethod(sp,"PetscSpaceSumGetNumSubspaces_C",(PetscSpace,PetscInt*),(sp,numSumSpaces));CHKERRQ(ierr); 23d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 24d092c84bSBrandon Whitchurch } 25d092c84bSBrandon Whitchurch 26d092c84bSBrandon Whitchurch /*@ 27d092c84bSBrandon Whitchurch PetscSpaceSumSetNumSubspaces - Set the number of spaces in the sum 28d092c84bSBrandon Whitchurch 29d092c84bSBrandon Whitchurch Input Parameters: 30d092c84bSBrandon Whitchurch + sp - the function space object 31d092c84bSBrandon Whitchurch - numSumSpaces - the number of spaces 32d092c84bSBrandon Whitchurch 33d092c84bSBrandon Whitchurch Level: intermediate 34d092c84bSBrandon Whitchurch 35d092c84bSBrandon Whitchurch .seealso: PetscSpaceSumGetNumSubspaces(), PetscSpaceSetDegree(), PetscSpaceSetNumVariables() 36d092c84bSBrandon Whitchurch @*/ 37d092c84bSBrandon Whitchurch PetscErrorCode PetscSpaceSumSetNumSubspaces(PetscSpace sp,PetscInt numSumSpaces) 38d092c84bSBrandon Whitchurch { 39d092c84bSBrandon Whitchurch PetscErrorCode ierr; 40d092c84bSBrandon Whitchurch 41d092c84bSBrandon Whitchurch PetscFunctionBegin; 42d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1); 43d092c84bSBrandon Whitchurch ierr = PetscTryMethod(sp,"PetscSpaceSumSetNumSubspaces_C",(PetscSpace,PetscInt),(sp,numSumSpaces));CHKERRQ(ierr); 44d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 45d092c84bSBrandon Whitchurch } 46d092c84bSBrandon Whitchurch 47d092c84bSBrandon Whitchurch /*@ 48d092c84bSBrandon Whitchurch PetscSpaceSumGetConcatenate - Get the concatenate flag for this space. 49d092c84bSBrandon 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, 50d092c84bSBrandon Whitchurch or direct sum space will have the same number of components as its subspaces . 51d092c84bSBrandon Whitchurch 52d092c84bSBrandon Whitchurch Input Parameters: 53d092c84bSBrandon Whitchurch . sp - the function space object 54d092c84bSBrandon Whitchurch 55d092c84bSBrandon Whitchurch Output Parameters: 56d092c84bSBrandon Whitchurch . concatenate - flag indicating whether subspaces are concatenated. 57d092c84bSBrandon Whitchurch 58d092c84bSBrandon Whitchurch Level: intermediate 59d092c84bSBrandon Whitchurch 60d092c84bSBrandon Whitchurch .seealso: PetscSpaceSumSetConcatenate() 61d092c84bSBrandon Whitchurch @*/ 62d092c84bSBrandon Whitchurch PetscErrorCode PetscSpaceSumGetConcatenate(PetscSpace sp,PetscBool *concatenate) 63d092c84bSBrandon Whitchurch { 64d092c84bSBrandon Whitchurch PetscErrorCode ierr; 65d092c84bSBrandon Whitchurch 66d092c84bSBrandon Whitchurch PetscFunctionBegin; 67d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1); 68d092c84bSBrandon Whitchurch ierr = PetscTryMethod(sp,"PetscSpaceSumGetConcatenate_C",(PetscSpace,PetscBool*),(sp,concatenate));CHKERRQ(ierr); 69d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 70d092c84bSBrandon Whitchurch } 71d092c84bSBrandon Whitchurch 72d092c84bSBrandon Whitchurch /*@ 73d092c84bSBrandon Whitchurch PetscSpaceSumSetConcatenate - Sets the concatenate flag for this space. 74d092c84bSBrandon 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, 75d092c84bSBrandon Whitchurch or direct sum space will have the same number of components as its subspaces . 76d092c84bSBrandon Whitchurch 77d092c84bSBrandon Whitchurch Input Parameters: 78d092c84bSBrandon Whitchurch + sp - the function space object 79d092c84bSBrandon Whitchurch - concatenate - are subspaces concatenated components (true) or direct summands (false) 80d092c84bSBrandon Whitchurch 81d092c84bSBrandon Whitchurch Level: intermediate 82d092c84bSBrandon Whitchurch .seealso: PetscSpaceSumGetConcatenate() 83d092c84bSBrandon Whitchurch @*/ 84d092c84bSBrandon Whitchurch PetscErrorCode PetscSpaceSumSetConcatenate(PetscSpace sp,PetscBool concatenate) 85d092c84bSBrandon Whitchurch { 86d092c84bSBrandon Whitchurch PetscErrorCode ierr; 87d092c84bSBrandon Whitchurch 88d092c84bSBrandon Whitchurch PetscFunctionBegin; 89d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1); 90d092c84bSBrandon Whitchurch ierr = PetscTryMethod(sp,"PetscSpaceSumSetConcatenate_C",(PetscSpace,PetscBool),(sp,concatenate));CHKERRQ(ierr); 91d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 92d092c84bSBrandon Whitchurch } 93d092c84bSBrandon Whitchurch 94d092c84bSBrandon Whitchurch /*@ 95d092c84bSBrandon Whitchurch PetscSpaceSumGetSubspace - Get a space in the sum 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: 102d092c84bSBrandon Whitchurch . subsp - the PetscSpace 103d092c84bSBrandon Whitchurch 104d092c84bSBrandon Whitchurch Level: intermediate 105d092c84bSBrandon Whitchurch 106d092c84bSBrandon Whitchurch .seealso: PetscSpaceSumSetSubspace(), PetscSpaceSetDegree(), PetscSpaceSetNumVariables() 107d092c84bSBrandon Whitchurch @*/ 108d092c84bSBrandon Whitchurch PetscErrorCode PetscSpaceSumGetSubspace(PetscSpace sp,PetscInt s,PetscSpace *subsp) 109d092c84bSBrandon Whitchurch { 110d092c84bSBrandon Whitchurch PetscErrorCode ierr; 111d092c84bSBrandon Whitchurch 112d092c84bSBrandon Whitchurch PetscFunctionBegin; 113d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1); 114d092c84bSBrandon Whitchurch PetscValidPointer(subsp,3); 115d092c84bSBrandon Whitchurch ierr = PetscTryMethod(sp,"PetscSpaceSumGetSubspace_C",(PetscSpace,PetscInt,PetscSpace*),(sp,s,subsp));CHKERRQ(ierr); 116d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 117d092c84bSBrandon Whitchurch } 118d092c84bSBrandon Whitchurch 119d092c84bSBrandon Whitchurch /*@ 120d092c84bSBrandon Whitchurch PetscSpaceSumSetSubspace - Set a space in the sum 121d092c84bSBrandon Whitchurch 122d092c84bSBrandon Whitchurch Input Parameters: 123d092c84bSBrandon Whitchurch + sp - the function space object 124d092c84bSBrandon Whitchurch . s - The space number 125d092c84bSBrandon Whitchurch - subsp - the number of spaces 126d092c84bSBrandon Whitchurch 127d092c84bSBrandon Whitchurch Level: intermediate 128d092c84bSBrandon Whitchurch 129d092c84bSBrandon Whitchurch .seealso: PetscSpaceSumGetSubspace(), PetscSpaceSetDegree(), PetscSpaceSetNumVariables() 130d092c84bSBrandon Whitchurch @*/ 131d092c84bSBrandon Whitchurch PetscErrorCode PetscSpaceSumSetSubspace(PetscSpace sp,PetscInt s,PetscSpace subsp) 132d092c84bSBrandon Whitchurch { 133d092c84bSBrandon Whitchurch PetscErrorCode ierr; 134d092c84bSBrandon Whitchurch 135d092c84bSBrandon Whitchurch PetscFunctionBegin; 136d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1); 137d092c84bSBrandon Whitchurch if (subsp) PetscValidHeaderSpecific(subsp,PETSCSPACE_CLASSID,3); 138d092c84bSBrandon Whitchurch ierr = PetscTryMethod(sp,"PetscSpaceSumSetSubspace_C",(PetscSpace,PetscInt,PetscSpace),(sp,s,subsp));CHKERRQ(ierr); 139d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 140d092c84bSBrandon Whitchurch } 141d092c84bSBrandon Whitchurch 142d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumGetNumSubspaces_Sum(PetscSpace space,PetscInt *numSumSpaces) 143d092c84bSBrandon Whitchurch { 144d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)space->data; 145d092c84bSBrandon Whitchurch 146d092c84bSBrandon Whitchurch PetscFunctionBegin; 147d092c84bSBrandon Whitchurch *numSumSpaces = sum->numSumSpaces; 148d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 149d092c84bSBrandon Whitchurch } 150d092c84bSBrandon Whitchurch 151d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumSetNumSubspaces_Sum(PetscSpace space,PetscInt numSumSpaces) 152d092c84bSBrandon Whitchurch { 153d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)space->data; 154d092c84bSBrandon Whitchurch PetscInt Ns = sum->numSumSpaces; 155d092c84bSBrandon Whitchurch PetscErrorCode ierr; 156d092c84bSBrandon Whitchurch 157d092c84bSBrandon Whitchurch PetscFunctionBegin; 158*d8185827SBarry Smith if (sum->setupCalled) SETERRQ(PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_WRONGSTATE,"Cannot change number of subspaces after setup called\n"); 159d092c84bSBrandon Whitchurch if (numSumSpaces == Ns) PetscFunctionReturn(0); 160d092c84bSBrandon Whitchurch if (Ns >= 0) { 161d092c84bSBrandon Whitchurch PetscInt s; 162d092c84bSBrandon Whitchurch for (s=0; s<Ns; ++s) { 163d092c84bSBrandon Whitchurch ierr = PetscSpaceDestroy(&sum->sumspaces[s]);CHKERRQ(ierr); 164d092c84bSBrandon Whitchurch } 165d092c84bSBrandon Whitchurch ierr = PetscFree(sum->sumspaces);CHKERRQ(ierr); 166d092c84bSBrandon Whitchurch } 167d092c84bSBrandon Whitchurch 168d092c84bSBrandon Whitchurch Ns = sum->numSumSpaces = numSumSpaces; 169d092c84bSBrandon Whitchurch ierr = PetscCalloc1(Ns,&sum->sumspaces);CHKERRQ(ierr); 170d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 171d092c84bSBrandon Whitchurch } 172d092c84bSBrandon Whitchurch 173d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumGetConcatenate_Sum(PetscSpace sp,PetscBool *concatenate) 174d092c84bSBrandon Whitchurch { 175d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 176d092c84bSBrandon Whitchurch 177d092c84bSBrandon Whitchurch PetscFunctionBegin; 178d092c84bSBrandon Whitchurch *concatenate = sum->concatenate; 179d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 180d092c84bSBrandon Whitchurch } 181d092c84bSBrandon Whitchurch 182d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumSetConcatenate_Sum(PetscSpace sp,PetscBool concatenate) 183d092c84bSBrandon Whitchurch { 184d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 185d092c84bSBrandon Whitchurch 186d092c84bSBrandon Whitchurch PetscFunctionBegin; 187d092c84bSBrandon Whitchurch if (sum->setupCalled) SETERRQ(PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_WRONGSTATE,"Cannot change space concatenation after setup called.\n"); 188d092c84bSBrandon Whitchurch 189d092c84bSBrandon Whitchurch sum->concatenate = concatenate; 190d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 191d092c84bSBrandon Whitchurch } 192d092c84bSBrandon Whitchurch 193d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumGetSubspace_Sum(PetscSpace space,PetscInt s,PetscSpace *subspace) 194d092c84bSBrandon Whitchurch { 195d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)space->data; 196d092c84bSBrandon Whitchurch PetscInt Ns = sum->numSumSpaces; 197d092c84bSBrandon Whitchurch 198d092c84bSBrandon Whitchurch PetscFunctionBegin; 199d092c84bSBrandon Whitchurch if (Ns < 0) SETERRQ(PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_WRONGSTATE,"Must call PetscSpaceSumSetNumSubspaces() first\n"); 200d092c84bSBrandon Whitchurch if (s<0 || s>=Ns) SETERRQ1 (PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_OUTOFRANGE,"Invalid subspace number %D\n",subspace); 201d092c84bSBrandon Whitchurch 202d092c84bSBrandon Whitchurch *subspace = sum->sumspaces[s]; 203d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 204d092c84bSBrandon Whitchurch } 205d092c84bSBrandon Whitchurch 206d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumSetSubspace_Sum(PetscSpace space,PetscInt s,PetscSpace subspace) 207d092c84bSBrandon Whitchurch { 208d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)space->data; 209d092c84bSBrandon Whitchurch PetscInt Ns = sum->numSumSpaces; 210d092c84bSBrandon Whitchurch PetscErrorCode ierr; 211d092c84bSBrandon Whitchurch 212d092c84bSBrandon Whitchurch PetscFunctionBegin; 213d092c84bSBrandon Whitchurch if (sum->setupCalled) SETERRQ(PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_WRONGSTATE,"Cannot change subspace after setup called\n"); 214d092c84bSBrandon Whitchurch if (Ns < 0) SETERRQ(PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_WRONGSTATE,"Must call PetscSpaceSumSetNumSubspaces() first\n"); 215d092c84bSBrandon Whitchurch if (s < 0 || s >= Ns) SETERRQ1(PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_OUTOFRANGE,"Invalid subspace number %D\n",subspace); 216d092c84bSBrandon Whitchurch 217d092c84bSBrandon Whitchurch ierr = PetscObjectReference((PetscObject)subspace);CHKERRQ(ierr); 218d092c84bSBrandon Whitchurch ierr = PetscSpaceDestroy(&sum->sumspaces[s]);CHKERRQ(ierr); 219d092c84bSBrandon Whitchurch sum->sumspaces[s] = subspace; 220d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 221d092c84bSBrandon Whitchurch } 222d092c84bSBrandon Whitchurch 223d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSetFromOptions_Sum(PetscOptionItems *PetscOptionsObject,PetscSpace sp) 224d092c84bSBrandon Whitchurch { 225d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 226d092c84bSBrandon Whitchurch PetscInt Ns,Nc,Nv,deg,i; 227d092c84bSBrandon Whitchurch PetscBool concatenate = PETSC_TRUE; 228d092c84bSBrandon Whitchurch const char *prefix; 229d092c84bSBrandon Whitchurch PetscErrorCode ierr; 230d092c84bSBrandon Whitchurch 231d092c84bSBrandon Whitchurch PetscFunctionBegin; 232d092c84bSBrandon Whitchurch ierr = PetscSpaceGetNumVariables(sp,&Nv);CHKERRQ(ierr); 233d092c84bSBrandon Whitchurch if (!Nv) PetscFunctionReturn(0); 234d092c84bSBrandon Whitchurch ierr = PetscSpaceGetNumComponents(sp,&Nc);CHKERRQ(ierr); 235d092c84bSBrandon Whitchurch ierr = PetscSpaceSumGetNumSubspaces(sp,&Ns);CHKERRQ(ierr); 236d092c84bSBrandon Whitchurch ierr = PetscSpaceGetDegree(sp,°,NULL);CHKERRQ(ierr); 237d092c84bSBrandon Whitchurch Ns = (Ns == PETSC_DEFAULT) ? 1 : Ns; 238d092c84bSBrandon Whitchurch 239d092c84bSBrandon Whitchurch ierr = PetscOptionsHead(PetscOptionsObject,"PetscSpace sum options");CHKERRQ(ierr); 240d092c84bSBrandon Whitchurch ierr = PetscOptionsBoundedInt("-petscspace_sum_spaces","The number of subspaces","PetscSpaceSumSetNumSubspaces",Ns,&Ns,NULL,0);CHKERRQ(ierr); 241d092c84bSBrandon Whitchurch ierr = PetscOptionsBool("-petscspace_sum_concatenate","Subspaces are concatenated components of the final space","PetscSpaceSumSetFromOptions", 242d092c84bSBrandon Whitchurch concatenate,&concatenate,NULL);CHKERRQ(ierr); 243d092c84bSBrandon Whitchurch ierr = PetscOptionsTail();CHKERRQ(ierr); 244d092c84bSBrandon Whitchurch 245d092c84bSBrandon Whitchurch if (Ns < 0 || (Nv > 0 && Ns == 0)) SETERRQ1(PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Cannot have a sum space of %D spaces\n",Ns); 246d092c84bSBrandon Whitchurch if (Ns != sum->numSumSpaces) { 247d092c84bSBrandon Whitchurch ierr = PetscSpaceSumSetNumSubspaces(sp,Ns);CHKERRQ(ierr); 248d092c84bSBrandon Whitchurch } 249d092c84bSBrandon Whitchurch ierr = PetscObjectGetOptionsPrefix((PetscObject)sp,&prefix);CHKERRQ(ierr); 250d092c84bSBrandon Whitchurch for (i=0; i<Ns; ++i) { 251d092c84bSBrandon Whitchurch PetscInt sNv; 252d092c84bSBrandon Whitchurch PetscSpace subspace; 253d092c84bSBrandon Whitchurch 254d092c84bSBrandon Whitchurch ierr = PetscSpaceSumGetSubspace(sp,i,&subspace);CHKERRQ(ierr); 255d092c84bSBrandon Whitchurch if (!subspace) { 256d092c84bSBrandon Whitchurch char subspacePrefix[256]; 257d092c84bSBrandon Whitchurch 258d092c84bSBrandon Whitchurch ierr = PetscSpaceCreate(PetscObjectComm((PetscObject)sp),&subspace);CHKERRQ(ierr); 259d092c84bSBrandon Whitchurch ierr = PetscObjectSetOptionsPrefix((PetscObject)subspace,prefix);CHKERRQ(ierr); 260d092c84bSBrandon Whitchurch ierr = PetscSNPrintf(subspacePrefix,256,"subspace%d_",i);CHKERRQ(ierr); 261d092c84bSBrandon Whitchurch ierr = PetscObjectAppendOptionsPrefix((PetscObject)subspace,subspacePrefix);CHKERRQ(ierr); 262d092c84bSBrandon Whitchurch } else { 263d092c84bSBrandon Whitchurch ierr = PetscObjectReference((PetscObject)subspace);CHKERRQ(ierr); 264d092c84bSBrandon Whitchurch } 265d092c84bSBrandon Whitchurch ierr = PetscSpaceSetFromOptions(subspace);CHKERRQ(ierr); 266d092c84bSBrandon Whitchurch ierr = PetscSpaceGetNumVariables(subspace,&sNv);CHKERRQ(ierr); 267*d8185827SBarry Smith if (!sNv) SETERRQ1(PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_WRONGSTATE,"Subspace %D has not been set properly, number of variables is 0.\n",i); 268d092c84bSBrandon Whitchurch ierr = PetscSpaceSumSetSubspace(sp,i,subspace);CHKERRQ(ierr); 269d092c84bSBrandon Whitchurch ierr = PetscSpaceDestroy(&subspace);CHKERRQ(ierr); 270d092c84bSBrandon Whitchurch } 271d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 272d092c84bSBrandon Whitchurch } 273d092c84bSBrandon Whitchurch 274d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSetUp_Sum(PetscSpace sp) 275d092c84bSBrandon Whitchurch { 276d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 277d092c84bSBrandon Whitchurch PetscBool concatenate = PETSC_TRUE; 278d092c84bSBrandon Whitchurch PetscInt Nv,Ns,Nc,i,sum_Nc = 0,deg = PETSC_MIN_INT,maxDeg = PETSC_MIN_INT; 279d092c84bSBrandon Whitchurch PetscErrorCode ierr; 280d092c84bSBrandon Whitchurch 281d092c84bSBrandon Whitchurch PetscFunctionBegin; 282d092c84bSBrandon Whitchurch if (sum->setupCalled) PetscFunctionReturn(0); 283d092c84bSBrandon Whitchurch 284d092c84bSBrandon Whitchurch ierr = PetscSpaceGetNumVariables(sp,&Nv);CHKERRQ(ierr); 285d092c84bSBrandon Whitchurch ierr = PetscSpaceGetNumComponents(sp,&Nc);CHKERRQ(ierr); 286d092c84bSBrandon Whitchurch ierr = PetscSpaceSumGetNumSubspaces(sp,&Ns);CHKERRQ(ierr); 287d092c84bSBrandon Whitchurch if (Ns == PETSC_DEFAULT) { 288d092c84bSBrandon Whitchurch Ns = 1; 289d092c84bSBrandon Whitchurch ierr = PetscSpaceSumSetNumSubspaces(sp,Ns);CHKERRQ(ierr); 290d092c84bSBrandon Whitchurch } 291d092c84bSBrandon Whitchurch if (!Ns && Nv) SETERRQ(PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Cannot have zero subspaces\n"); 292d092c84bSBrandon Whitchurch 293d092c84bSBrandon Whitchurch for (i=0; i<Ns; ++i) { 294d092c84bSBrandon Whitchurch PetscInt sNv,sNc,iDeg,iMaxDeg; 295d092c84bSBrandon Whitchurch PetscSpace si; 296d092c84bSBrandon Whitchurch 297d092c84bSBrandon Whitchurch ierr = PetscSpaceSumGetSubspace(sp,i,&si);CHKERRQ(ierr); 298d092c84bSBrandon Whitchurch ierr = PetscSpaceSetUp(si);CHKERRQ(ierr); 299d092c84bSBrandon Whitchurch ierr = PetscSpaceGetNumVariables(si,&sNv);CHKERRQ(ierr); 300d092c84bSBrandon Whitchurch if (sNv != Nv) SETERRQ3(PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_WRONGSTATE,"Subspace %D has %D variables, space has %D.\n",i,sNv,Nv); 301d092c84bSBrandon Whitchurch ierr = PetscSpaceGetNumComponents(si,&sNc);CHKERRQ(ierr); 302d092c84bSBrandon Whitchurch if (i == 0 && sNc == Nc) concatenate = PETSC_FALSE; 303d092c84bSBrandon Whitchurch sum_Nc += sNc; 304d092c84bSBrandon Whitchurch ierr = PetscSpaceSumGetSubspace(sp,i,&si);CHKERRQ(ierr); 305d092c84bSBrandon Whitchurch ierr = PetscSpaceGetDegree(si,&iDeg,&iMaxDeg);CHKERRQ(ierr); 306d092c84bSBrandon Whitchurch deg = PetscMax(deg,iDeg); 307d092c84bSBrandon Whitchurch maxDeg = PetscMax(maxDeg,iMaxDeg); 308d092c84bSBrandon Whitchurch } 309d092c84bSBrandon Whitchurch 310d092c84bSBrandon Whitchurch if (concatenate) { 311d092c84bSBrandon Whitchurch if (sum_Nc != Nc) { 312*d8185827SBarry Smith SETERRQ2(PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Total number of subspace components (%D) does not match number of target space components (%D).",sum_Nc,Nc); 313d092c84bSBrandon Whitchurch } 314d092c84bSBrandon Whitchurch } else { 315*d8185827SBarry Smith if (sum_Nc != Ns*Nc) SETERRQ(PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Subspaces must have same number of components as the target space."); 316d092c84bSBrandon Whitchurch } 317d092c84bSBrandon Whitchurch 318d092c84bSBrandon Whitchurch sp->degree = deg; 319d092c84bSBrandon Whitchurch sp->maxDegree = maxDeg; 320d092c84bSBrandon Whitchurch sum->concatenate = concatenate; 321d092c84bSBrandon Whitchurch sum->setupCalled = PETSC_TRUE; 322d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 323d092c84bSBrandon Whitchurch } 324d092c84bSBrandon Whitchurch 325d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumView_Ascii(PetscSpace sp,PetscViewer v) 326d092c84bSBrandon Whitchurch { 327d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 328d092c84bSBrandon Whitchurch PetscBool concatenate = sum->concatenate; 329d092c84bSBrandon Whitchurch PetscInt i,Ns = sum->numSumSpaces; 330d092c84bSBrandon Whitchurch PetscErrorCode ierr; 331d092c84bSBrandon Whitchurch 332d092c84bSBrandon Whitchurch PetscFunctionBegin; 333d092c84bSBrandon Whitchurch if (concatenate) { 334d092c84bSBrandon Whitchurch ierr = PetscViewerASCIIPrintf(v,"Sum space of %D concatenated subspaces\n",Ns);CHKERRQ(ierr); 335d092c84bSBrandon Whitchurch } else { 336d092c84bSBrandon Whitchurch ierr = PetscViewerASCIIPrintf(v,"Sum space of %D subspaces\n",Ns);CHKERRQ(ierr); 337d092c84bSBrandon Whitchurch } 338d092c84bSBrandon Whitchurch for (i=0; i<Ns; ++i) { 339d092c84bSBrandon Whitchurch ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr); 340d092c84bSBrandon Whitchurch ierr = PetscSpaceView(sum->sumspaces[i],v);CHKERRQ(ierr); 341d092c84bSBrandon Whitchurch ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr); 342d092c84bSBrandon Whitchurch } 343d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 344d092c84bSBrandon Whitchurch } 345d092c84bSBrandon Whitchurch 346d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceView_Sum(PetscSpace sp,PetscViewer viewer) 347d092c84bSBrandon Whitchurch { 348d092c84bSBrandon Whitchurch PetscBool iascii; 349d092c84bSBrandon Whitchurch PetscErrorCode ierr; 350d092c84bSBrandon Whitchurch 351d092c84bSBrandon Whitchurch PetscFunctionBegin; 352d092c84bSBrandon Whitchurch ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 353d092c84bSBrandon Whitchurch if (iascii) { 354d092c84bSBrandon Whitchurch ierr = PetscSpaceSumView_Ascii(sp,viewer);CHKERRQ(ierr); 355d092c84bSBrandon Whitchurch } 356d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 357d092c84bSBrandon Whitchurch } 358d092c84bSBrandon Whitchurch 359d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceDestroy_Sum(PetscSpace sp) 360d092c84bSBrandon Whitchurch { 361d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 362d092c84bSBrandon Whitchurch PetscInt i,Ns = sum->numSumSpaces; 363d092c84bSBrandon Whitchurch PetscErrorCode ierr; 364d092c84bSBrandon Whitchurch 365d092c84bSBrandon Whitchurch PetscFunctionBegin; 366d092c84bSBrandon Whitchurch for (i=0; i<Ns; ++i) { 367d092c84bSBrandon Whitchurch ierr = PetscSpaceDestroy(&sum->sumspaces[i]);CHKERRQ(ierr); 368d092c84bSBrandon Whitchurch } 369d092c84bSBrandon Whitchurch ierr = PetscFree(sum->sumspaces);CHKERRQ(ierr); 370d092c84bSBrandon Whitchurch ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetSubspace_C",NULL);CHKERRQ(ierr); 371d092c84bSBrandon Whitchurch ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetSubspace_C",NULL);CHKERRQ(ierr); 372d092c84bSBrandon Whitchurch ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetNumSubspaces_C",NULL);CHKERRQ(ierr); 373d092c84bSBrandon Whitchurch ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetNumSubspaces_C",NULL);CHKERRQ(ierr); 374d092c84bSBrandon Whitchurch ierr = PetscFree(sum);CHKERRQ(ierr); 375d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 376d092c84bSBrandon Whitchurch } 377d092c84bSBrandon Whitchurch 378d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceGetDimension_Sum(PetscSpace sp,PetscInt *dim) 379d092c84bSBrandon Whitchurch { 380d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 381d092c84bSBrandon Whitchurch PetscInt i,d = 0,Ns = sum->numSumSpaces; 382d092c84bSBrandon Whitchurch PetscErrorCode ierr; 383d092c84bSBrandon Whitchurch 384d092c84bSBrandon Whitchurch PetscFunctionBegin; 385d092c84bSBrandon Whitchurch ierr = PetscSpaceSetUp(sp);CHKERRQ(ierr); 386d092c84bSBrandon Whitchurch 387d092c84bSBrandon Whitchurch for (i=0; i<Ns; ++i) { 388d092c84bSBrandon Whitchurch PetscInt id; 389d092c84bSBrandon Whitchurch 390d092c84bSBrandon Whitchurch ierr = PetscSpaceGetDimension(sum->sumspaces[i],&id);CHKERRQ(ierr); 391d092c84bSBrandon Whitchurch d += id; 392d092c84bSBrandon Whitchurch } 393d092c84bSBrandon Whitchurch 394d092c84bSBrandon Whitchurch *dim = d; 395d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 396d092c84bSBrandon Whitchurch } 397d092c84bSBrandon Whitchurch 398d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceEvaluate_Sum(PetscSpace sp,PetscInt npoints,const PetscReal points[],PetscReal B[],PetscReal D[],PetscReal H[]) 399d092c84bSBrandon Whitchurch { 400d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 401d092c84bSBrandon Whitchurch PetscBool concatenate = sum->concatenate; 402d092c84bSBrandon Whitchurch DM dm = sp->dm; 403d092c84bSBrandon Whitchurch PetscInt Nc = sp->Nc,Nv = sp->Nv,Ns = sum->numSumSpaces; 404d092c84bSBrandon Whitchurch PetscInt i,s,offset,ncoffset,pdimfull,numelB,numelD,numelH; 405d092c84bSBrandon Whitchurch PetscReal *sB = NULL,*sD = NULL,*sH = NULL; 406d092c84bSBrandon Whitchurch PetscErrorCode ierr; 407d092c84bSBrandon Whitchurch 408d092c84bSBrandon Whitchurch PetscFunctionBegin; 409d092c84bSBrandon Whitchurch if (!sum->setupCalled) { 410d092c84bSBrandon Whitchurch ierr = PetscSpaceSetUp(sp);CHKERRQ(ierr); 411d092c84bSBrandon Whitchurch } 412d092c84bSBrandon Whitchurch ierr = PetscSpaceGetDimension(sp,&pdimfull);CHKERRQ(ierr); 413d092c84bSBrandon Whitchurch numelB = npoints*pdimfull*Nc; 414d092c84bSBrandon Whitchurch numelD = numelB*Nv; 415d092c84bSBrandon Whitchurch numelH = numelD*Nv; 416d092c84bSBrandon Whitchurch if (B || D || H) { 417d092c84bSBrandon Whitchurch ierr = DMGetWorkArray(dm,numelB,MPIU_REAL,&sB);CHKERRQ(ierr); 418d092c84bSBrandon Whitchurch } 419d092c84bSBrandon Whitchurch if (D || H) { 420d092c84bSBrandon Whitchurch ierr = DMGetWorkArray(dm,numelD,MPIU_REAL,&sD);CHKERRQ(ierr); 421d092c84bSBrandon Whitchurch } 422d092c84bSBrandon Whitchurch if (H) { 423d092c84bSBrandon Whitchurch ierr = DMGetWorkArray(dm,numelH,MPIU_REAL,&sH);CHKERRQ(ierr); 424d092c84bSBrandon Whitchurch } 425d092c84bSBrandon Whitchurch if (B) 426d092c84bSBrandon Whitchurch for (i=0; i<numelB; ++i) B[i] = 0.; 427d092c84bSBrandon Whitchurch if (D) 428d092c84bSBrandon Whitchurch for (i=0; i<numelD; ++i) D[i] = 0.; 429d092c84bSBrandon Whitchurch if (H) 430d092c84bSBrandon Whitchurch for (i=0; i<numelH; ++i) H[i] = 0.; 431d092c84bSBrandon Whitchurch 432d092c84bSBrandon Whitchurch for (s=0,offset=0,ncoffset=0; s<Ns; ++s) { 433d092c84bSBrandon Whitchurch PetscInt sNv,spdim,sNc,p; 434d092c84bSBrandon Whitchurch 435d092c84bSBrandon Whitchurch ierr = PetscSpaceGetNumVariables(sum->sumspaces[s],&sNv);CHKERRQ(ierr); 436d092c84bSBrandon Whitchurch ierr = PetscSpaceGetNumComponents(sum->sumspaces[s],&sNc);CHKERRQ(ierr); 437d092c84bSBrandon Whitchurch ierr = PetscSpaceGetDimension(sum->sumspaces[s],&spdim);CHKERRQ(ierr); 438*d8185827SBarry Smith if (offset + spdim > pdimfull) SETERRQ(PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Subspace dimensions exceed target space dimension.\n"); 439d092c84bSBrandon Whitchurch ierr = PetscSpaceEvaluate(sum->sumspaces[s],npoints,points,sB,sD,sH);CHKERRQ(ierr); 440d092c84bSBrandon Whitchurch if (B || D || H) { 441d092c84bSBrandon Whitchurch for (p=0; p<npoints; ++p) { 442d092c84bSBrandon Whitchurch PetscInt j; 443d092c84bSBrandon Whitchurch 444d092c84bSBrandon Whitchurch for (j=0; j<spdim; ++j) { 445d092c84bSBrandon Whitchurch PetscInt c; 446d092c84bSBrandon Whitchurch 447d092c84bSBrandon Whitchurch for (c=0; c<sNc; ++c) { 448d092c84bSBrandon Whitchurch PetscInt compoffset,BInd,sBInd; 449d092c84bSBrandon Whitchurch 450d092c84bSBrandon Whitchurch compoffset = concatenate ? c+ncoffset : c; 451d092c84bSBrandon Whitchurch BInd = (p*pdimfull + j + offset)*Nc + compoffset; 452d092c84bSBrandon Whitchurch sBInd = (p*spdim + j)*sNc + c; 453d092c84bSBrandon Whitchurch if (B) B[BInd] += sB[sBInd]; 454d092c84bSBrandon Whitchurch if (D || H) { 455d092c84bSBrandon Whitchurch PetscInt v; 456d092c84bSBrandon Whitchurch 457d092c84bSBrandon Whitchurch for (v=0; v<Nv; ++v) { 458d092c84bSBrandon Whitchurch PetscInt DInd,sDInd; 459d092c84bSBrandon Whitchurch 460d092c84bSBrandon Whitchurch DInd = BInd*Nv + v; 461d092c84bSBrandon Whitchurch sDInd = sBInd*Nv + v; 462d092c84bSBrandon Whitchurch if (D) D[DInd] +=sD[sDInd]; 463d092c84bSBrandon Whitchurch if (H) { 464d092c84bSBrandon Whitchurch PetscInt v2; 465d092c84bSBrandon Whitchurch 466d092c84bSBrandon Whitchurch for (v2=0; v2<Nv; ++v2) { 467d092c84bSBrandon Whitchurch PetscInt HInd,sHInd; 468d092c84bSBrandon Whitchurch 469d092c84bSBrandon Whitchurch HInd = DInd*Nv + v2; 470d092c84bSBrandon Whitchurch sHInd = sDInd*Nv + v2; 471d092c84bSBrandon Whitchurch H[HInd] += sH[sHInd]; 472d092c84bSBrandon Whitchurch } 473d092c84bSBrandon Whitchurch } 474d092c84bSBrandon Whitchurch } 475d092c84bSBrandon Whitchurch } 476d092c84bSBrandon Whitchurch } 477d092c84bSBrandon Whitchurch } 478d092c84bSBrandon Whitchurch } 479d092c84bSBrandon Whitchurch } 480d092c84bSBrandon Whitchurch offset += spdim; 481d092c84bSBrandon Whitchurch ncoffset += sNc; 482d092c84bSBrandon Whitchurch } 483d092c84bSBrandon Whitchurch 484d092c84bSBrandon Whitchurch if (H) { 485d092c84bSBrandon Whitchurch ierr = DMRestoreWorkArray(dm,numelH,MPIU_REAL,&sH);CHKERRQ(ierr); 486d092c84bSBrandon Whitchurch } 487d092c84bSBrandon Whitchurch if (D || H) { 488d092c84bSBrandon Whitchurch ierr = DMRestoreWorkArray(dm,numelD,MPIU_REAL,&sD);CHKERRQ(ierr); 489d092c84bSBrandon Whitchurch } 490d092c84bSBrandon Whitchurch if (B || D || H) { 491d092c84bSBrandon Whitchurch ierr = DMRestoreWorkArray(dm,numelB,MPIU_REAL,&sB);CHKERRQ(ierr); 492d092c84bSBrandon Whitchurch } 493d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 494d092c84bSBrandon Whitchurch } 495d092c84bSBrandon Whitchurch 496d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceInitialize_Sum(PetscSpace sp) 497d092c84bSBrandon Whitchurch { 498d092c84bSBrandon Whitchurch PetscErrorCode ierr; 499d092c84bSBrandon Whitchurch 500d092c84bSBrandon Whitchurch PetscFunctionBegin; 501d092c84bSBrandon Whitchurch sp->ops->setfromoptions = PetscSpaceSetFromOptions_Sum; 502d092c84bSBrandon Whitchurch sp->ops->setup = PetscSpaceSetUp_Sum; 503d092c84bSBrandon Whitchurch sp->ops->view = PetscSpaceView_Sum; 504d092c84bSBrandon Whitchurch sp->ops->destroy = PetscSpaceDestroy_Sum; 505d092c84bSBrandon Whitchurch sp->ops->getdimension = PetscSpaceGetDimension_Sum; 506d092c84bSBrandon Whitchurch sp->ops->evaluate = PetscSpaceEvaluate_Sum; 507d092c84bSBrandon Whitchurch 508d092c84bSBrandon Whitchurch ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetNumSubspaces_C",PetscSpaceSumGetNumSubspaces_Sum);CHKERRQ(ierr); 509d092c84bSBrandon Whitchurch ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetNumSubspaces_C",PetscSpaceSumSetNumSubspaces_Sum);CHKERRQ(ierr); 510d092c84bSBrandon Whitchurch ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetSubspace_C",PetscSpaceSumGetSubspace_Sum);CHKERRQ(ierr); 511d092c84bSBrandon Whitchurch ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetSubspace_C",PetscSpaceSumSetSubspace_Sum);CHKERRQ(ierr); 512d092c84bSBrandon Whitchurch ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetConcatenate_C",PetscSpaceSumGetConcatenate_Sum);CHKERRQ(ierr); 513d092c84bSBrandon Whitchurch ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetConcatenate_C",PetscSpaceSumSetConcatenate_Sum);CHKERRQ(ierr); 514d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 515d092c84bSBrandon Whitchurch } 516d092c84bSBrandon Whitchurch 517d092c84bSBrandon Whitchurch /*MC 518d092c84bSBrandon Whitchurch PETSCSPACESUM = "sum" - A PetscSpace object that encapsulates a sum of subspaces. 519d092c84bSBrandon Whitchurch That sum can either be direct or concatenate a concatenation.For example if A and B are spaces each with 2 components, 520d092c84bSBrandon Whitchurch the direct sum of A and B will also have 2 components while the concatenated sum will have 4 components.In both cases A and B must be defined over the 521d092c84bSBrandon Whitchurch same number of variables. 522d092c84bSBrandon Whitchurch 523d092c84bSBrandon Whitchurch Level: intermediate 524d092c84bSBrandon Whitchurch 525d092c84bSBrandon Whitchurch .seealso: PetscSpaceType, PetscSpaceCreate(), PetscSpaceSetType() 526d092c84bSBrandon Whitchurch M*/ 527d092c84bSBrandon Whitchurch PETSC_EXTERN PetscErrorCode PetscSpaceCreate_Sum(PetscSpace sp) 528d092c84bSBrandon Whitchurch { 529d092c84bSBrandon Whitchurch PetscSpace_Sum *sum; 530d092c84bSBrandon Whitchurch PetscErrorCode ierr; 531d092c84bSBrandon Whitchurch 532d092c84bSBrandon Whitchurch PetscFunctionBegin; 533d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1); 534d092c84bSBrandon Whitchurch ierr = PetscNewLog(sp,&sum);CHKERRQ(ierr); 535d092c84bSBrandon Whitchurch sp->data = sum; 536d092c84bSBrandon Whitchurch ierr = PetscSpaceInitialize_Sum(sp);CHKERRQ(ierr); 537d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 538d092c84bSBrandon Whitchurch } 539d092c84bSBrandon Whitchurch 540d092c84bSBrandon Whitchurch PETSC_EXTERN PetscErrorCode PetscSpaceCreateSum(PetscInt numSubspaces,const PetscSpace subspaces[],PetscBool concatenate,PetscSpace *sumSpace) 541d092c84bSBrandon Whitchurch { 542d092c84bSBrandon Whitchurch PetscInt i,Nv,Nc = 0; 543d092c84bSBrandon Whitchurch PetscErrorCode ierr; 544d092c84bSBrandon Whitchurch 545d092c84bSBrandon Whitchurch PetscFunctionBegin; 546d092c84bSBrandon Whitchurch if (sumSpace) { 547d092c84bSBrandon Whitchurch ierr = PetscSpaceDestroy(sumSpace);CHKERRQ(ierr); 548d092c84bSBrandon Whitchurch } 549d092c84bSBrandon Whitchurch ierr = PetscSpaceCreate(PetscObjectComm((PetscObject)subspaces[0]),sumSpace);CHKERRQ(ierr); 550d092c84bSBrandon Whitchurch ierr = PetscSpaceSetType(*sumSpace,PETSCSPACESUM);CHKERRQ(ierr); 551d092c84bSBrandon Whitchurch ierr = PetscSpaceSumSetNumSubspaces(*sumSpace,numSubspaces);CHKERRQ(ierr); 552d092c84bSBrandon Whitchurch ierr = PetscSpaceSumSetConcatenate(*sumSpace,concatenate);CHKERRQ(ierr); 553d092c84bSBrandon Whitchurch for (i=0; i<numSubspaces; ++i) { 554d092c84bSBrandon Whitchurch PetscInt sNc; 555d092c84bSBrandon Whitchurch 556d092c84bSBrandon Whitchurch ierr = PetscSpaceSumSetSubspace(*sumSpace,i,subspaces[i]);CHKERRQ(ierr); 557d092c84bSBrandon Whitchurch ierr = PetscSpaceGetNumComponents(subspaces[i],&sNc);CHKERRQ(ierr); 558d092c84bSBrandon Whitchurch if (concatenate) Nc += sNc; 559d092c84bSBrandon Whitchurch else Nc = sNc; 560d092c84bSBrandon Whitchurch } 561d092c84bSBrandon Whitchurch ierr = PetscSpaceGetNumVariables(subspaces[0],&Nv);CHKERRQ(ierr); 562d092c84bSBrandon Whitchurch ierr = PetscSpaceSetNumComponents(*sumSpace,Nc);CHKERRQ(ierr); 563d092c84bSBrandon Whitchurch ierr = PetscSpaceSetNumVariables(*sumSpace,Nv);CHKERRQ(ierr); 564d092c84bSBrandon Whitchurch ierr = PetscSpaceSetUp(*sumSpace);CHKERRQ(ierr); 565d092c84bSBrandon Whitchurch 566d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 567d092c84bSBrandon Whitchurch } 568