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*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(sum->setupCalled,PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_WRONGSTATE,"Cannot change number of subspaces after setup called"); 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; 187*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(sum->setupCalled,PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_WRONGSTATE,"Cannot change space concatenation after setup called."); 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; 199*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(Ns < 0,PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_WRONGSTATE,"Must call PetscSpaceSumSetNumSubspaces() first"); 200*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(s<0 || s>=Ns,PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_OUTOFRANGE,"Invalid subspace number %D",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; 213*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(sum->setupCalled,PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_WRONGSTATE,"Cannot change subspace after setup called"); 214*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(Ns < 0,PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_WRONGSTATE,"Must call PetscSpaceSumSetNumSubspaces() first"); 215*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(s < 0 || s >= Ns,PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_OUTOFRANGE,"Invalid subspace number %D",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 245*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(Ns < 0 || (Nv > 0 && Ns == 0),PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Cannot have a sum space of %D spaces",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); 260417c287bSToby Isaac ierr = PetscSNPrintf(subspacePrefix,256,"sumcomp_%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*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!sNv,PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_WRONGSTATE,"Subspace %D has not been set properly, number of variables is 0.",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; 278642c7897SToby Isaac PetscBool uniform; 279642c7897SToby Isaac PetscInt Nv,Ns,Nc,i,sum_Nc = 0,deg = PETSC_MAX_INT,maxDeg = PETSC_MIN_INT; 280642c7897SToby Isaac PetscInt minNc,maxNc; 281d092c84bSBrandon Whitchurch PetscErrorCode ierr; 282d092c84bSBrandon Whitchurch 283d092c84bSBrandon Whitchurch PetscFunctionBegin; 284d092c84bSBrandon Whitchurch if (sum->setupCalled) PetscFunctionReturn(0); 285d092c84bSBrandon Whitchurch 286d092c84bSBrandon Whitchurch ierr = PetscSpaceGetNumVariables(sp,&Nv);CHKERRQ(ierr); 287d092c84bSBrandon Whitchurch ierr = PetscSpaceGetNumComponents(sp,&Nc);CHKERRQ(ierr); 288d092c84bSBrandon Whitchurch ierr = PetscSpaceSumGetNumSubspaces(sp,&Ns);CHKERRQ(ierr); 289d092c84bSBrandon Whitchurch if (Ns == PETSC_DEFAULT) { 290d092c84bSBrandon Whitchurch Ns = 1; 291d092c84bSBrandon Whitchurch ierr = PetscSpaceSumSetNumSubspaces(sp,Ns);CHKERRQ(ierr); 292d092c84bSBrandon Whitchurch } 293*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(Ns < 0,PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Cannot have %D subspaces", Ns); 294642c7897SToby Isaac uniform = PETSC_TRUE; 295642c7897SToby Isaac if (Ns) { 296642c7897SToby Isaac PetscSpace s0; 297d092c84bSBrandon Whitchurch 298642c7897SToby Isaac ierr = PetscSpaceSumGetSubspace(sp,0,&s0);CHKERRQ(ierr); 299642c7897SToby Isaac for (PetscInt i = 1; i < Ns; i++) { 300642c7897SToby Isaac PetscSpace si; 301642c7897SToby Isaac 302642c7897SToby Isaac ierr = PetscSpaceSumGetSubspace(sp,i,&si);CHKERRQ(ierr); 303642c7897SToby Isaac if (si != s0) { 304642c7897SToby Isaac uniform = PETSC_FALSE; 305642c7897SToby Isaac break; 306642c7897SToby Isaac } 307642c7897SToby Isaac } 308642c7897SToby Isaac } 309642c7897SToby Isaac 310642c7897SToby Isaac minNc = Nc; 311642c7897SToby Isaac maxNc = Nc; 312d092c84bSBrandon Whitchurch for (i=0; i<Ns; ++i) { 313d092c84bSBrandon Whitchurch PetscInt sNv,sNc,iDeg,iMaxDeg; 314d092c84bSBrandon Whitchurch PetscSpace si; 315d092c84bSBrandon Whitchurch 316d092c84bSBrandon Whitchurch ierr = PetscSpaceSumGetSubspace(sp,i,&si);CHKERRQ(ierr); 317d092c84bSBrandon Whitchurch ierr = PetscSpaceSetUp(si);CHKERRQ(ierr); 318d092c84bSBrandon Whitchurch ierr = PetscSpaceGetNumVariables(si,&sNv);CHKERRQ(ierr); 319*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(sNv != Nv,PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_WRONGSTATE,"Subspace %D has %D variables, space has %D.",i,sNv,Nv); 320d092c84bSBrandon Whitchurch ierr = PetscSpaceGetNumComponents(si,&sNc);CHKERRQ(ierr); 321d092c84bSBrandon Whitchurch if (i == 0 && sNc == Nc) concatenate = PETSC_FALSE; 322642c7897SToby Isaac minNc = PetscMin(minNc, sNc); 323642c7897SToby Isaac maxNc = PetscMax(maxNc, sNc); 324d092c84bSBrandon Whitchurch sum_Nc += sNc; 325d092c84bSBrandon Whitchurch ierr = PetscSpaceSumGetSubspace(sp,i,&si);CHKERRQ(ierr); 326d092c84bSBrandon Whitchurch ierr = PetscSpaceGetDegree(si,&iDeg,&iMaxDeg);CHKERRQ(ierr); 327642c7897SToby Isaac deg = PetscMin(deg,iDeg); 328d092c84bSBrandon Whitchurch maxDeg = PetscMax(maxDeg,iMaxDeg); 329d092c84bSBrandon Whitchurch } 330d092c84bSBrandon Whitchurch 331d092c84bSBrandon Whitchurch if (concatenate) { 332d092c84bSBrandon Whitchurch if (sum_Nc != Nc) { 33398921bdaSJacob Faibussowitsch SETERRQ(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); 334d092c84bSBrandon Whitchurch } 335d092c84bSBrandon Whitchurch } else { 336*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(minNc != Nc || maxNc != Nc,PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Subspaces must have same number of components as the target space."); 337d092c84bSBrandon Whitchurch } 338d092c84bSBrandon Whitchurch 339d092c84bSBrandon Whitchurch sp->degree = deg; 340d092c84bSBrandon Whitchurch sp->maxDegree = maxDeg; 341d092c84bSBrandon Whitchurch sum->concatenate = concatenate; 342642c7897SToby Isaac sum->uniform = uniform; 343d092c84bSBrandon Whitchurch sum->setupCalled = PETSC_TRUE; 344d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 345d092c84bSBrandon Whitchurch } 346d092c84bSBrandon Whitchurch 347d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumView_Ascii(PetscSpace sp,PetscViewer v) 348d092c84bSBrandon Whitchurch { 349d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 350d092c84bSBrandon Whitchurch PetscBool concatenate = sum->concatenate; 351d092c84bSBrandon Whitchurch PetscInt i,Ns = sum->numSumSpaces; 352d092c84bSBrandon Whitchurch PetscErrorCode ierr; 353d092c84bSBrandon Whitchurch 354d092c84bSBrandon Whitchurch PetscFunctionBegin; 355d092c84bSBrandon Whitchurch if (concatenate) { 356642c7897SToby Isaac ierr = PetscViewerASCIIPrintf(v,"Sum space of %D concatenated subspaces%s\n",Ns, sum->uniform ? " (all identical)": "");CHKERRQ(ierr); 357d092c84bSBrandon Whitchurch } else { 358642c7897SToby Isaac ierr = PetscViewerASCIIPrintf(v,"Sum space of %D subspaces%s\n",Ns, sum->uniform ? " (all identical)" : "");CHKERRQ(ierr); 359d092c84bSBrandon Whitchurch } 360642c7897SToby Isaac for (i=0; i < (sum->uniform ? (Ns > 0 ? 1 : 0) : Ns); ++i) { 361d092c84bSBrandon Whitchurch ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr); 362d092c84bSBrandon Whitchurch ierr = PetscSpaceView(sum->sumspaces[i],v);CHKERRQ(ierr); 363d092c84bSBrandon Whitchurch ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr); 364d092c84bSBrandon Whitchurch } 365d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 366d092c84bSBrandon Whitchurch } 367d092c84bSBrandon Whitchurch 368d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceView_Sum(PetscSpace sp,PetscViewer viewer) 369d092c84bSBrandon Whitchurch { 370d092c84bSBrandon Whitchurch PetscBool iascii; 371d092c84bSBrandon Whitchurch PetscErrorCode ierr; 372d092c84bSBrandon Whitchurch 373d092c84bSBrandon Whitchurch PetscFunctionBegin; 374d092c84bSBrandon Whitchurch ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 375d092c84bSBrandon Whitchurch if (iascii) { 376d092c84bSBrandon Whitchurch ierr = PetscSpaceSumView_Ascii(sp,viewer);CHKERRQ(ierr); 377d092c84bSBrandon Whitchurch } 378d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 379d092c84bSBrandon Whitchurch } 380d092c84bSBrandon Whitchurch 381d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceDestroy_Sum(PetscSpace sp) 382d092c84bSBrandon Whitchurch { 383d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 384d092c84bSBrandon Whitchurch PetscInt i,Ns = sum->numSumSpaces; 385d092c84bSBrandon Whitchurch PetscErrorCode ierr; 386d092c84bSBrandon Whitchurch 387d092c84bSBrandon Whitchurch PetscFunctionBegin; 388d092c84bSBrandon Whitchurch for (i=0; i<Ns; ++i) { 389d092c84bSBrandon Whitchurch ierr = PetscSpaceDestroy(&sum->sumspaces[i]);CHKERRQ(ierr); 390d092c84bSBrandon Whitchurch } 391d092c84bSBrandon Whitchurch ierr = PetscFree(sum->sumspaces);CHKERRQ(ierr); 392642c7897SToby Isaac if (sum->heightsubspaces) { 393642c7897SToby Isaac PetscInt d; 394642c7897SToby Isaac 395642c7897SToby Isaac /* sp->Nv is the spatial dimension, so it is equal to the number 396642c7897SToby Isaac * of subspaces on higher co-dimension points */ 397642c7897SToby Isaac for (d = 0; d < sp->Nv; ++d) { 398642c7897SToby Isaac ierr = PetscSpaceDestroy(&sum->heightsubspaces[d]);CHKERRQ(ierr); 399642c7897SToby Isaac } 400642c7897SToby Isaac } 401642c7897SToby Isaac ierr = PetscFree(sum->heightsubspaces);CHKERRQ(ierr); 402d092c84bSBrandon Whitchurch ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetSubspace_C",NULL);CHKERRQ(ierr); 403d092c84bSBrandon Whitchurch ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetSubspace_C",NULL);CHKERRQ(ierr); 404d092c84bSBrandon Whitchurch ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetNumSubspaces_C",NULL);CHKERRQ(ierr); 405d092c84bSBrandon Whitchurch ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetNumSubspaces_C",NULL);CHKERRQ(ierr); 406d092c84bSBrandon Whitchurch ierr = PetscFree(sum);CHKERRQ(ierr); 407d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 408d092c84bSBrandon Whitchurch } 409d092c84bSBrandon Whitchurch 410d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceGetDimension_Sum(PetscSpace sp,PetscInt *dim) 411d092c84bSBrandon Whitchurch { 412d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 413d092c84bSBrandon Whitchurch PetscInt i,d = 0,Ns = sum->numSumSpaces; 414d092c84bSBrandon Whitchurch PetscErrorCode ierr; 415d092c84bSBrandon Whitchurch 416d092c84bSBrandon Whitchurch PetscFunctionBegin; 417642c7897SToby Isaac if (!sum->setupCalled) { 418d092c84bSBrandon Whitchurch ierr = PetscSpaceSetUp(sp);CHKERRQ(ierr); 419642c7897SToby Isaac ierr = PetscSpaceGetDimension(sp, dim);CHKERRQ(ierr); 420642c7897SToby Isaac PetscFunctionReturn(0); 421642c7897SToby Isaac } 422d092c84bSBrandon Whitchurch 423d092c84bSBrandon Whitchurch for (i=0; i<Ns; ++i) { 424d092c84bSBrandon Whitchurch PetscInt id; 425d092c84bSBrandon Whitchurch 426d092c84bSBrandon Whitchurch ierr = PetscSpaceGetDimension(sum->sumspaces[i],&id);CHKERRQ(ierr); 427d092c84bSBrandon Whitchurch d += id; 428d092c84bSBrandon Whitchurch } 429d092c84bSBrandon Whitchurch 430d092c84bSBrandon Whitchurch *dim = d; 431d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 432d092c84bSBrandon Whitchurch } 433d092c84bSBrandon Whitchurch 434d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceEvaluate_Sum(PetscSpace sp,PetscInt npoints,const PetscReal points[],PetscReal B[],PetscReal D[],PetscReal H[]) 435d092c84bSBrandon Whitchurch { 436d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 437d092c84bSBrandon Whitchurch PetscBool concatenate = sum->concatenate; 438d092c84bSBrandon Whitchurch DM dm = sp->dm; 439d092c84bSBrandon Whitchurch PetscInt Nc = sp->Nc,Nv = sp->Nv,Ns = sum->numSumSpaces; 440d092c84bSBrandon Whitchurch PetscInt i,s,offset,ncoffset,pdimfull,numelB,numelD,numelH; 441d092c84bSBrandon Whitchurch PetscReal *sB = NULL,*sD = NULL,*sH = NULL; 442d092c84bSBrandon Whitchurch PetscErrorCode ierr; 443d092c84bSBrandon Whitchurch 444d092c84bSBrandon Whitchurch PetscFunctionBegin; 445d092c84bSBrandon Whitchurch if (!sum->setupCalled) { 446d092c84bSBrandon Whitchurch ierr = PetscSpaceSetUp(sp);CHKERRQ(ierr); 447642c7897SToby Isaac ierr = PetscSpaceEvaluate(sp, npoints, points, B, D, H);CHKERRQ(ierr); 448642c7897SToby Isaac PetscFunctionReturn(0); 449d092c84bSBrandon Whitchurch } 450d092c84bSBrandon Whitchurch ierr = PetscSpaceGetDimension(sp,&pdimfull);CHKERRQ(ierr); 451d092c84bSBrandon Whitchurch numelB = npoints*pdimfull*Nc; 452d092c84bSBrandon Whitchurch numelD = numelB*Nv; 453d092c84bSBrandon Whitchurch numelH = numelD*Nv; 454d092c84bSBrandon Whitchurch if (B || D || H) { 455d092c84bSBrandon Whitchurch ierr = DMGetWorkArray(dm,numelB,MPIU_REAL,&sB);CHKERRQ(ierr); 456d092c84bSBrandon Whitchurch } 457d092c84bSBrandon Whitchurch if (D || H) { 458d092c84bSBrandon Whitchurch ierr = DMGetWorkArray(dm,numelD,MPIU_REAL,&sD);CHKERRQ(ierr); 459d092c84bSBrandon Whitchurch } 460d092c84bSBrandon Whitchurch if (H) { 461d092c84bSBrandon Whitchurch ierr = DMGetWorkArray(dm,numelH,MPIU_REAL,&sH);CHKERRQ(ierr); 462d092c84bSBrandon Whitchurch } 463d092c84bSBrandon Whitchurch if (B) 464d092c84bSBrandon Whitchurch for (i=0; i<numelB; ++i) B[i] = 0.; 465d092c84bSBrandon Whitchurch if (D) 466d092c84bSBrandon Whitchurch for (i=0; i<numelD; ++i) D[i] = 0.; 467d092c84bSBrandon Whitchurch if (H) 468d092c84bSBrandon Whitchurch for (i=0; i<numelH; ++i) H[i] = 0.; 469d092c84bSBrandon Whitchurch 470d092c84bSBrandon Whitchurch for (s=0,offset=0,ncoffset=0; s<Ns; ++s) { 471d092c84bSBrandon Whitchurch PetscInt sNv,spdim,sNc,p; 472d092c84bSBrandon Whitchurch 473d092c84bSBrandon Whitchurch ierr = PetscSpaceGetNumVariables(sum->sumspaces[s],&sNv);CHKERRQ(ierr); 474d092c84bSBrandon Whitchurch ierr = PetscSpaceGetNumComponents(sum->sumspaces[s],&sNc);CHKERRQ(ierr); 475d092c84bSBrandon Whitchurch ierr = PetscSpaceGetDimension(sum->sumspaces[s],&spdim);CHKERRQ(ierr); 476*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(offset + spdim > pdimfull,PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Subspace dimensions exceed target space dimension."); 477642c7897SToby Isaac if (s == 0 || !sum->uniform) { 478d092c84bSBrandon Whitchurch ierr = PetscSpaceEvaluate(sum->sumspaces[s],npoints,points,sB,sD,sH);CHKERRQ(ierr); 479642c7897SToby Isaac } 480d092c84bSBrandon Whitchurch if (B || D || H) { 481d092c84bSBrandon Whitchurch for (p=0; p<npoints; ++p) { 482d092c84bSBrandon Whitchurch PetscInt j; 483d092c84bSBrandon Whitchurch 484d092c84bSBrandon Whitchurch for (j=0; j<spdim; ++j) { 485d092c84bSBrandon Whitchurch PetscInt c; 486d092c84bSBrandon Whitchurch 487d092c84bSBrandon Whitchurch for (c=0; c<sNc; ++c) { 488d092c84bSBrandon Whitchurch PetscInt compoffset,BInd,sBInd; 489d092c84bSBrandon Whitchurch 490d092c84bSBrandon Whitchurch compoffset = concatenate ? c+ncoffset : c; 491d092c84bSBrandon Whitchurch BInd = (p*pdimfull + j + offset)*Nc + compoffset; 492d092c84bSBrandon Whitchurch sBInd = (p*spdim + j)*sNc + c; 493642c7897SToby Isaac if (B) B[BInd] = sB[sBInd]; 494d092c84bSBrandon Whitchurch if (D || H) { 495d092c84bSBrandon Whitchurch PetscInt v; 496d092c84bSBrandon Whitchurch 497d092c84bSBrandon Whitchurch for (v=0; v<Nv; ++v) { 498d092c84bSBrandon Whitchurch PetscInt DInd,sDInd; 499d092c84bSBrandon Whitchurch 500d092c84bSBrandon Whitchurch DInd = BInd*Nv + v; 501d092c84bSBrandon Whitchurch sDInd = sBInd*Nv + v; 502642c7897SToby Isaac if (D) D[DInd] = sD[sDInd]; 503d092c84bSBrandon Whitchurch if (H) { 504d092c84bSBrandon Whitchurch PetscInt v2; 505d092c84bSBrandon Whitchurch 506d092c84bSBrandon Whitchurch for (v2=0; v2<Nv; ++v2) { 507d092c84bSBrandon Whitchurch PetscInt HInd,sHInd; 508d092c84bSBrandon Whitchurch 509d092c84bSBrandon Whitchurch HInd = DInd*Nv + v2; 510d092c84bSBrandon Whitchurch sHInd = sDInd*Nv + v2; 511642c7897SToby Isaac H[HInd] = sH[sHInd]; 512d092c84bSBrandon Whitchurch } 513d092c84bSBrandon Whitchurch } 514d092c84bSBrandon Whitchurch } 515d092c84bSBrandon Whitchurch } 516d092c84bSBrandon Whitchurch } 517d092c84bSBrandon Whitchurch } 518d092c84bSBrandon Whitchurch } 519d092c84bSBrandon Whitchurch } 520d092c84bSBrandon Whitchurch offset += spdim; 521d092c84bSBrandon Whitchurch ncoffset += sNc; 522d092c84bSBrandon Whitchurch } 523d092c84bSBrandon Whitchurch 524d092c84bSBrandon Whitchurch if (H) { 525d092c84bSBrandon Whitchurch ierr = DMRestoreWorkArray(dm,numelH,MPIU_REAL,&sH);CHKERRQ(ierr); 526d092c84bSBrandon Whitchurch } 527d092c84bSBrandon Whitchurch if (D || H) { 528d092c84bSBrandon Whitchurch ierr = DMRestoreWorkArray(dm,numelD,MPIU_REAL,&sD);CHKERRQ(ierr); 529d092c84bSBrandon Whitchurch } 530d092c84bSBrandon Whitchurch if (B || D || H) { 531d092c84bSBrandon Whitchurch ierr = DMRestoreWorkArray(dm,numelB,MPIU_REAL,&sB);CHKERRQ(ierr); 532d092c84bSBrandon Whitchurch } 533d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 534d092c84bSBrandon Whitchurch } 535d092c84bSBrandon Whitchurch 536642c7897SToby Isaac static PetscErrorCode PetscSpaceGetHeightSubspace_Sum(PetscSpace sp, PetscInt height, PetscSpace *subsp) 537642c7897SToby Isaac { 538642c7897SToby Isaac PetscSpace_Sum *sum = (PetscSpace_Sum *) sp->data; 539642c7897SToby Isaac PetscInt Nc, dim, order; 540642c7897SToby Isaac PetscBool tensor; 541642c7897SToby Isaac PetscErrorCode ierr; 542642c7897SToby Isaac 543642c7897SToby Isaac PetscFunctionBegin; 544642c7897SToby Isaac ierr = PetscSpaceGetNumComponents(sp, &Nc);CHKERRQ(ierr); 545642c7897SToby Isaac ierr = PetscSpaceGetNumVariables(sp, &dim);CHKERRQ(ierr); 546642c7897SToby Isaac ierr = PetscSpaceGetDegree(sp, &order, NULL);CHKERRQ(ierr); 547642c7897SToby Isaac ierr = PetscSpacePolynomialGetTensor(sp, &tensor);CHKERRQ(ierr); 548*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(height > dim || height < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Asked for space at height %D for dimension %D space", height, dim); 549642c7897SToby Isaac if (!sum->heightsubspaces) {ierr = PetscCalloc1(dim, &sum->heightsubspaces);CHKERRQ(ierr);} 550642c7897SToby Isaac if (height <= dim) { 551642c7897SToby Isaac if (!sum->heightsubspaces[height-1]) { 552642c7897SToby Isaac PetscSpace sub; 553642c7897SToby Isaac const char *name; 554642c7897SToby Isaac 555642c7897SToby Isaac ierr = PetscSpaceCreate(PetscObjectComm((PetscObject) sp), &sub);CHKERRQ(ierr); 556642c7897SToby Isaac ierr = PetscObjectGetName((PetscObject) sp, &name);CHKERRQ(ierr); 557642c7897SToby Isaac ierr = PetscObjectSetName((PetscObject) sub, name);CHKERRQ(ierr); 558642c7897SToby Isaac ierr = PetscSpaceSetType(sub, PETSCSPACESUM);CHKERRQ(ierr); 559642c7897SToby Isaac ierr = PetscSpaceSumSetNumSubspaces(sub, sum->numSumSpaces);CHKERRQ(ierr); 560642c7897SToby Isaac ierr = PetscSpaceSumSetConcatenate(sub, sum->concatenate);CHKERRQ(ierr); 561642c7897SToby Isaac ierr = PetscSpaceSetNumComponents(sub, Nc);CHKERRQ(ierr); 562642c7897SToby Isaac ierr = PetscSpaceSetNumVariables(sub, dim-height);CHKERRQ(ierr); 563642c7897SToby Isaac for (PetscInt i = 0; i < sum->numSumSpaces; i++) { 564642c7897SToby Isaac PetscSpace subh; 565642c7897SToby Isaac 566642c7897SToby Isaac ierr = PetscSpaceGetHeightSubspace(sum->sumspaces[i], height, &subh);CHKERRQ(ierr); 567642c7897SToby Isaac ierr = PetscSpaceSumSetSubspace(sub, i, subh);CHKERRQ(ierr); 568642c7897SToby Isaac } 569642c7897SToby Isaac ierr = PetscSpaceSetUp(sub);CHKERRQ(ierr); 570642c7897SToby Isaac sum->heightsubspaces[height-1] = sub; 571642c7897SToby Isaac } 572642c7897SToby Isaac *subsp = sum->heightsubspaces[height-1]; 573642c7897SToby Isaac } else { 574642c7897SToby Isaac *subsp = NULL; 575642c7897SToby Isaac } 576642c7897SToby Isaac PetscFunctionReturn(0); 577642c7897SToby Isaac } 578642c7897SToby Isaac 579d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceInitialize_Sum(PetscSpace sp) 580d092c84bSBrandon Whitchurch { 581d092c84bSBrandon Whitchurch PetscErrorCode ierr; 582d092c84bSBrandon Whitchurch 583d092c84bSBrandon Whitchurch PetscFunctionBegin; 584d092c84bSBrandon Whitchurch sp->ops->setfromoptions = PetscSpaceSetFromOptions_Sum; 585d092c84bSBrandon Whitchurch sp->ops->setup = PetscSpaceSetUp_Sum; 586d092c84bSBrandon Whitchurch sp->ops->view = PetscSpaceView_Sum; 587d092c84bSBrandon Whitchurch sp->ops->destroy = PetscSpaceDestroy_Sum; 588d092c84bSBrandon Whitchurch sp->ops->getdimension = PetscSpaceGetDimension_Sum; 589d092c84bSBrandon Whitchurch sp->ops->evaluate = PetscSpaceEvaluate_Sum; 590642c7897SToby Isaac sp->ops->getheightsubspace = PetscSpaceGetHeightSubspace_Sum; 591d092c84bSBrandon Whitchurch 592d092c84bSBrandon Whitchurch ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetNumSubspaces_C",PetscSpaceSumGetNumSubspaces_Sum);CHKERRQ(ierr); 593d092c84bSBrandon Whitchurch ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetNumSubspaces_C",PetscSpaceSumSetNumSubspaces_Sum);CHKERRQ(ierr); 594d092c84bSBrandon Whitchurch ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetSubspace_C",PetscSpaceSumGetSubspace_Sum);CHKERRQ(ierr); 595d092c84bSBrandon Whitchurch ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetSubspace_C",PetscSpaceSumSetSubspace_Sum);CHKERRQ(ierr); 596d092c84bSBrandon Whitchurch ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetConcatenate_C",PetscSpaceSumGetConcatenate_Sum);CHKERRQ(ierr); 597d092c84bSBrandon Whitchurch ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetConcatenate_C",PetscSpaceSumSetConcatenate_Sum);CHKERRQ(ierr); 598d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 599d092c84bSBrandon Whitchurch } 600d092c84bSBrandon Whitchurch 601d092c84bSBrandon Whitchurch /*MC 602d092c84bSBrandon Whitchurch PETSCSPACESUM = "sum" - A PetscSpace object that encapsulates a sum of subspaces. 603d092c84bSBrandon Whitchurch That sum can either be direct or concatenate a concatenation.For example if A and B are spaces each with 2 components, 604d092c84bSBrandon 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 605d092c84bSBrandon Whitchurch same number of variables. 606d092c84bSBrandon Whitchurch 607d092c84bSBrandon Whitchurch Level: intermediate 608d092c84bSBrandon Whitchurch 609d092c84bSBrandon Whitchurch .seealso: PetscSpaceType, PetscSpaceCreate(), PetscSpaceSetType() 610d092c84bSBrandon Whitchurch M*/ 611d092c84bSBrandon Whitchurch PETSC_EXTERN PetscErrorCode PetscSpaceCreate_Sum(PetscSpace sp) 612d092c84bSBrandon Whitchurch { 613d092c84bSBrandon Whitchurch PetscSpace_Sum *sum; 614d092c84bSBrandon Whitchurch PetscErrorCode ierr; 615d092c84bSBrandon Whitchurch 616d092c84bSBrandon Whitchurch PetscFunctionBegin; 617d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1); 618d092c84bSBrandon Whitchurch ierr = PetscNewLog(sp,&sum);CHKERRQ(ierr); 619642c7897SToby Isaac sum->numSumSpaces = PETSC_DEFAULT; 620d092c84bSBrandon Whitchurch sp->data = sum; 621d092c84bSBrandon Whitchurch ierr = PetscSpaceInitialize_Sum(sp);CHKERRQ(ierr); 622d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 623d092c84bSBrandon Whitchurch } 624d092c84bSBrandon Whitchurch 625d092c84bSBrandon Whitchurch PETSC_EXTERN PetscErrorCode PetscSpaceCreateSum(PetscInt numSubspaces,const PetscSpace subspaces[],PetscBool concatenate,PetscSpace *sumSpace) 626d092c84bSBrandon Whitchurch { 627d092c84bSBrandon Whitchurch PetscInt i,Nv,Nc = 0; 628d092c84bSBrandon Whitchurch PetscErrorCode ierr; 629d092c84bSBrandon Whitchurch 630d092c84bSBrandon Whitchurch PetscFunctionBegin; 631d092c84bSBrandon Whitchurch if (sumSpace) { 632d092c84bSBrandon Whitchurch ierr = PetscSpaceDestroy(sumSpace);CHKERRQ(ierr); 633d092c84bSBrandon Whitchurch } 634d092c84bSBrandon Whitchurch ierr = PetscSpaceCreate(PetscObjectComm((PetscObject)subspaces[0]),sumSpace);CHKERRQ(ierr); 635d092c84bSBrandon Whitchurch ierr = PetscSpaceSetType(*sumSpace,PETSCSPACESUM);CHKERRQ(ierr); 636d092c84bSBrandon Whitchurch ierr = PetscSpaceSumSetNumSubspaces(*sumSpace,numSubspaces);CHKERRQ(ierr); 637d092c84bSBrandon Whitchurch ierr = PetscSpaceSumSetConcatenate(*sumSpace,concatenate);CHKERRQ(ierr); 638d092c84bSBrandon Whitchurch for (i=0; i<numSubspaces; ++i) { 639d092c84bSBrandon Whitchurch PetscInt sNc; 640d092c84bSBrandon Whitchurch 641d092c84bSBrandon Whitchurch ierr = PetscSpaceSumSetSubspace(*sumSpace,i,subspaces[i]);CHKERRQ(ierr); 642d092c84bSBrandon Whitchurch ierr = PetscSpaceGetNumComponents(subspaces[i],&sNc);CHKERRQ(ierr); 643d092c84bSBrandon Whitchurch if (concatenate) Nc += sNc; 644d092c84bSBrandon Whitchurch else Nc = sNc; 645d092c84bSBrandon Whitchurch } 646d092c84bSBrandon Whitchurch ierr = PetscSpaceGetNumVariables(subspaces[0],&Nv);CHKERRQ(ierr); 647d092c84bSBrandon Whitchurch ierr = PetscSpaceSetNumComponents(*sumSpace,Nc);CHKERRQ(ierr); 648d092c84bSBrandon Whitchurch ierr = PetscSpaceSetNumVariables(*sumSpace,Nv);CHKERRQ(ierr); 649d092c84bSBrandon Whitchurch ierr = PetscSpaceSetUp(*sumSpace);CHKERRQ(ierr); 650d092c84bSBrandon Whitchurch 651d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 652d092c84bSBrandon Whitchurch } 653