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 PetscFunctionBegin; 18d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1); 19d092c84bSBrandon Whitchurch PetscValidIntPointer(numSumSpaces,2); 20*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTryMethod(sp,"PetscSpaceSumGetNumSubspaces_C",(PetscSpace,PetscInt*),(sp,numSumSpaces))); 21d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 22d092c84bSBrandon Whitchurch } 23d092c84bSBrandon Whitchurch 24d092c84bSBrandon Whitchurch /*@ 25d092c84bSBrandon Whitchurch PetscSpaceSumSetNumSubspaces - Set the number of spaces in the sum 26d092c84bSBrandon Whitchurch 27d092c84bSBrandon Whitchurch Input Parameters: 28d092c84bSBrandon Whitchurch + sp - the function space object 29d092c84bSBrandon Whitchurch - numSumSpaces - the number of spaces 30d092c84bSBrandon Whitchurch 31d092c84bSBrandon Whitchurch Level: intermediate 32d092c84bSBrandon Whitchurch 33d092c84bSBrandon Whitchurch .seealso: PetscSpaceSumGetNumSubspaces(), PetscSpaceSetDegree(), PetscSpaceSetNumVariables() 34d092c84bSBrandon Whitchurch @*/ 35d092c84bSBrandon Whitchurch PetscErrorCode PetscSpaceSumSetNumSubspaces(PetscSpace sp,PetscInt numSumSpaces) 36d092c84bSBrandon Whitchurch { 37d092c84bSBrandon Whitchurch PetscFunctionBegin; 38d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1); 39*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTryMethod(sp,"PetscSpaceSumSetNumSubspaces_C",(PetscSpace,PetscInt),(sp,numSumSpaces))); 40d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 41d092c84bSBrandon Whitchurch } 42d092c84bSBrandon Whitchurch 43d092c84bSBrandon Whitchurch /*@ 44d092c84bSBrandon Whitchurch PetscSpaceSumGetConcatenate - Get the concatenate flag for this space. 45d092c84bSBrandon 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, 46d092c84bSBrandon Whitchurch or direct sum space will have the same number of components as its subspaces . 47d092c84bSBrandon Whitchurch 48d092c84bSBrandon Whitchurch Input Parameters: 49d092c84bSBrandon Whitchurch . sp - the function space object 50d092c84bSBrandon Whitchurch 51d092c84bSBrandon Whitchurch Output Parameters: 52d092c84bSBrandon Whitchurch . concatenate - flag indicating whether subspaces are concatenated. 53d092c84bSBrandon Whitchurch 54d092c84bSBrandon Whitchurch Level: intermediate 55d092c84bSBrandon Whitchurch 56d092c84bSBrandon Whitchurch .seealso: PetscSpaceSumSetConcatenate() 57d092c84bSBrandon Whitchurch @*/ 58d092c84bSBrandon Whitchurch PetscErrorCode PetscSpaceSumGetConcatenate(PetscSpace sp,PetscBool *concatenate) 59d092c84bSBrandon Whitchurch { 60d092c84bSBrandon Whitchurch PetscFunctionBegin; 61d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1); 62*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTryMethod(sp,"PetscSpaceSumGetConcatenate_C",(PetscSpace,PetscBool*),(sp,concatenate))); 63d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 64d092c84bSBrandon Whitchurch } 65d092c84bSBrandon Whitchurch 66d092c84bSBrandon Whitchurch /*@ 67d092c84bSBrandon Whitchurch PetscSpaceSumSetConcatenate - Sets the concatenate flag for this space. 68d092c84bSBrandon 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, 69d092c84bSBrandon Whitchurch or direct sum space will have the same number of components as its subspaces . 70d092c84bSBrandon Whitchurch 71d092c84bSBrandon Whitchurch Input Parameters: 72d092c84bSBrandon Whitchurch + sp - the function space object 73d092c84bSBrandon Whitchurch - concatenate - are subspaces concatenated components (true) or direct summands (false) 74d092c84bSBrandon Whitchurch 75d092c84bSBrandon Whitchurch Level: intermediate 76d092c84bSBrandon Whitchurch .seealso: PetscSpaceSumGetConcatenate() 77d092c84bSBrandon Whitchurch @*/ 78d092c84bSBrandon Whitchurch PetscErrorCode PetscSpaceSumSetConcatenate(PetscSpace sp,PetscBool concatenate) 79d092c84bSBrandon Whitchurch { 80d092c84bSBrandon Whitchurch PetscFunctionBegin; 81d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1); 82*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTryMethod(sp,"PetscSpaceSumSetConcatenate_C",(PetscSpace,PetscBool),(sp,concatenate))); 83d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 84d092c84bSBrandon Whitchurch } 85d092c84bSBrandon Whitchurch 86d092c84bSBrandon Whitchurch /*@ 87d092c84bSBrandon Whitchurch PetscSpaceSumGetSubspace - Get a space in the sum 88d092c84bSBrandon Whitchurch 89d092c84bSBrandon Whitchurch Input Parameters: 90d092c84bSBrandon Whitchurch + sp - the function space object 91d092c84bSBrandon Whitchurch - s - The space number 92d092c84bSBrandon Whitchurch 93d092c84bSBrandon Whitchurch Output Parameter: 94d092c84bSBrandon Whitchurch . subsp - the PetscSpace 95d092c84bSBrandon Whitchurch 96d092c84bSBrandon Whitchurch Level: intermediate 97d092c84bSBrandon Whitchurch 98d092c84bSBrandon Whitchurch .seealso: PetscSpaceSumSetSubspace(), PetscSpaceSetDegree(), PetscSpaceSetNumVariables() 99d092c84bSBrandon Whitchurch @*/ 100d092c84bSBrandon Whitchurch PetscErrorCode PetscSpaceSumGetSubspace(PetscSpace sp,PetscInt s,PetscSpace *subsp) 101d092c84bSBrandon Whitchurch { 102d092c84bSBrandon Whitchurch PetscFunctionBegin; 103d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1); 104d092c84bSBrandon Whitchurch PetscValidPointer(subsp,3); 105*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTryMethod(sp,"PetscSpaceSumGetSubspace_C",(PetscSpace,PetscInt,PetscSpace*),(sp,s,subsp))); 106d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 107d092c84bSBrandon Whitchurch } 108d092c84bSBrandon Whitchurch 109d092c84bSBrandon Whitchurch /*@ 110d092c84bSBrandon Whitchurch PetscSpaceSumSetSubspace - Set a space in the sum 111d092c84bSBrandon Whitchurch 112d092c84bSBrandon Whitchurch Input Parameters: 113d092c84bSBrandon Whitchurch + sp - the function space object 114d092c84bSBrandon Whitchurch . s - The space number 115d092c84bSBrandon Whitchurch - subsp - the number of spaces 116d092c84bSBrandon Whitchurch 117d092c84bSBrandon Whitchurch Level: intermediate 118d092c84bSBrandon Whitchurch 119d092c84bSBrandon Whitchurch .seealso: PetscSpaceSumGetSubspace(), PetscSpaceSetDegree(), PetscSpaceSetNumVariables() 120d092c84bSBrandon Whitchurch @*/ 121d092c84bSBrandon Whitchurch PetscErrorCode PetscSpaceSumSetSubspace(PetscSpace sp,PetscInt s,PetscSpace subsp) 122d092c84bSBrandon Whitchurch { 123d092c84bSBrandon Whitchurch PetscFunctionBegin; 124d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1); 125d092c84bSBrandon Whitchurch if (subsp) PetscValidHeaderSpecific(subsp,PETSCSPACE_CLASSID,3); 126*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTryMethod(sp,"PetscSpaceSumSetSubspace_C",(PetscSpace,PetscInt,PetscSpace),(sp,s,subsp))); 127d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 128d092c84bSBrandon Whitchurch } 129d092c84bSBrandon Whitchurch 130d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumGetNumSubspaces_Sum(PetscSpace space,PetscInt *numSumSpaces) 131d092c84bSBrandon Whitchurch { 132d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)space->data; 133d092c84bSBrandon Whitchurch 134d092c84bSBrandon Whitchurch PetscFunctionBegin; 135d092c84bSBrandon Whitchurch *numSumSpaces = sum->numSumSpaces; 136d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 137d092c84bSBrandon Whitchurch } 138d092c84bSBrandon Whitchurch 139d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumSetNumSubspaces_Sum(PetscSpace space,PetscInt numSumSpaces) 140d092c84bSBrandon Whitchurch { 141d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)space->data; 142d092c84bSBrandon Whitchurch PetscInt Ns = sum->numSumSpaces; 143d092c84bSBrandon Whitchurch 144d092c84bSBrandon Whitchurch PetscFunctionBegin; 1452c71b3e2SJacob Faibussowitsch PetscCheckFalse(sum->setupCalled,PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_WRONGSTATE,"Cannot change number of subspaces after setup called"); 146d092c84bSBrandon Whitchurch if (numSumSpaces == Ns) PetscFunctionReturn(0); 147d092c84bSBrandon Whitchurch if (Ns >= 0) { 148d092c84bSBrandon Whitchurch PetscInt s; 149d092c84bSBrandon Whitchurch for (s=0; s<Ns; ++s) { 150*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceDestroy(&sum->sumspaces[s])); 151d092c84bSBrandon Whitchurch } 152*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(sum->sumspaces)); 153d092c84bSBrandon Whitchurch } 154d092c84bSBrandon Whitchurch 155d092c84bSBrandon Whitchurch Ns = sum->numSumSpaces = numSumSpaces; 156*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscCalloc1(Ns,&sum->sumspaces)); 157d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 158d092c84bSBrandon Whitchurch } 159d092c84bSBrandon Whitchurch 160d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumGetConcatenate_Sum(PetscSpace sp,PetscBool *concatenate) 161d092c84bSBrandon Whitchurch { 162d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 163d092c84bSBrandon Whitchurch 164d092c84bSBrandon Whitchurch PetscFunctionBegin; 165d092c84bSBrandon Whitchurch *concatenate = sum->concatenate; 166d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 167d092c84bSBrandon Whitchurch } 168d092c84bSBrandon Whitchurch 169d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumSetConcatenate_Sum(PetscSpace sp,PetscBool concatenate) 170d092c84bSBrandon Whitchurch { 171d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 172d092c84bSBrandon Whitchurch 173d092c84bSBrandon Whitchurch PetscFunctionBegin; 1742c71b3e2SJacob Faibussowitsch PetscCheckFalse(sum->setupCalled,PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_WRONGSTATE,"Cannot change space concatenation after setup called."); 175d092c84bSBrandon Whitchurch 176d092c84bSBrandon Whitchurch sum->concatenate = concatenate; 177d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 178d092c84bSBrandon Whitchurch } 179d092c84bSBrandon Whitchurch 180d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumGetSubspace_Sum(PetscSpace space,PetscInt s,PetscSpace *subspace) 181d092c84bSBrandon Whitchurch { 182d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)space->data; 183d092c84bSBrandon Whitchurch PetscInt Ns = sum->numSumSpaces; 184d092c84bSBrandon Whitchurch 185d092c84bSBrandon Whitchurch PetscFunctionBegin; 1862c71b3e2SJacob Faibussowitsch PetscCheckFalse(Ns < 0,PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_WRONGSTATE,"Must call PetscSpaceSumSetNumSubspaces() first"); 1872c71b3e2SJacob Faibussowitsch PetscCheckFalse(s<0 || s>=Ns,PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_OUTOFRANGE,"Invalid subspace number %D",subspace); 188d092c84bSBrandon Whitchurch 189d092c84bSBrandon Whitchurch *subspace = sum->sumspaces[s]; 190d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 191d092c84bSBrandon Whitchurch } 192d092c84bSBrandon Whitchurch 193d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumSetSubspace_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; 1992c71b3e2SJacob Faibussowitsch PetscCheckFalse(sum->setupCalled,PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_WRONGSTATE,"Cannot change subspace after setup called"); 2002c71b3e2SJacob Faibussowitsch PetscCheckFalse(Ns < 0,PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_WRONGSTATE,"Must call PetscSpaceSumSetNumSubspaces() first"); 2012c71b3e2SJacob Faibussowitsch PetscCheckFalse(s < 0 || s >= Ns,PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_OUTOFRANGE,"Invalid subspace number %D",subspace); 202d092c84bSBrandon Whitchurch 203*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectReference((PetscObject)subspace)); 204*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceDestroy(&sum->sumspaces[s])); 205d092c84bSBrandon Whitchurch sum->sumspaces[s] = subspace; 206d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 207d092c84bSBrandon Whitchurch } 208d092c84bSBrandon Whitchurch 209d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSetFromOptions_Sum(PetscOptionItems *PetscOptionsObject,PetscSpace sp) 210d092c84bSBrandon Whitchurch { 211d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 212d092c84bSBrandon Whitchurch PetscInt Ns,Nc,Nv,deg,i; 213d092c84bSBrandon Whitchurch PetscBool concatenate = PETSC_TRUE; 214d092c84bSBrandon Whitchurch const char *prefix; 215d092c84bSBrandon Whitchurch PetscErrorCode ierr; 216d092c84bSBrandon Whitchurch 217d092c84bSBrandon Whitchurch PetscFunctionBegin; 218*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetNumVariables(sp,&Nv)); 219d092c84bSBrandon Whitchurch if (!Nv) PetscFunctionReturn(0); 220*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetNumComponents(sp,&Nc)); 221*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSumGetNumSubspaces(sp,&Ns)); 222*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetDegree(sp,°,NULL)); 223d092c84bSBrandon Whitchurch Ns = (Ns == PETSC_DEFAULT) ? 1 : Ns; 224d092c84bSBrandon Whitchurch 225*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsHead(PetscOptionsObject,"PetscSpace sum options")); 226*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsBoundedInt("-petscspace_sum_spaces","The number of subspaces","PetscSpaceSumSetNumSubspaces",Ns,&Ns,NULL,0)); 227d092c84bSBrandon Whitchurch ierr = PetscOptionsBool("-petscspace_sum_concatenate","Subspaces are concatenated components of the final space","PetscSpaceSumSetFromOptions", 228d092c84bSBrandon Whitchurch concatenate,&concatenate,NULL);CHKERRQ(ierr); 229*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsTail()); 230d092c84bSBrandon Whitchurch 2312c71b3e2SJacob Faibussowitsch PetscCheckFalse(Ns < 0 || (Nv > 0 && Ns == 0),PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Cannot have a sum space of %D spaces",Ns); 232d092c84bSBrandon Whitchurch if (Ns != sum->numSumSpaces) { 233*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSumSetNumSubspaces(sp,Ns)); 234d092c84bSBrandon Whitchurch } 235*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectGetOptionsPrefix((PetscObject)sp,&prefix)); 236d092c84bSBrandon Whitchurch for (i=0; i<Ns; ++i) { 237d092c84bSBrandon Whitchurch PetscInt sNv; 238d092c84bSBrandon Whitchurch PetscSpace subspace; 239d092c84bSBrandon Whitchurch 240*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSumGetSubspace(sp,i,&subspace)); 241d092c84bSBrandon Whitchurch if (!subspace) { 242d092c84bSBrandon Whitchurch char subspacePrefix[256]; 243d092c84bSBrandon Whitchurch 244*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceCreate(PetscObjectComm((PetscObject)sp),&subspace)); 245*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectSetOptionsPrefix((PetscObject)subspace,prefix)); 246*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSNPrintf(subspacePrefix,256,"sumcomp_%D_",i)); 247*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectAppendOptionsPrefix((PetscObject)subspace,subspacePrefix)); 248d092c84bSBrandon Whitchurch } else { 249*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectReference((PetscObject)subspace)); 250d092c84bSBrandon Whitchurch } 251*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetFromOptions(subspace)); 252*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetNumVariables(subspace,&sNv)); 2532c71b3e2SJacob Faibussowitsch PetscCheckFalse(!sNv,PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_WRONGSTATE,"Subspace %D has not been set properly, number of variables is 0.",i); 254*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSumSetSubspace(sp,i,subspace)); 255*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceDestroy(&subspace)); 256d092c84bSBrandon Whitchurch } 257d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 258d092c84bSBrandon Whitchurch } 259d092c84bSBrandon Whitchurch 260d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSetUp_Sum(PetscSpace sp) 261d092c84bSBrandon Whitchurch { 262d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 263d092c84bSBrandon Whitchurch PetscBool concatenate = PETSC_TRUE; 264642c7897SToby Isaac PetscBool uniform; 265642c7897SToby Isaac PetscInt Nv,Ns,Nc,i,sum_Nc = 0,deg = PETSC_MAX_INT,maxDeg = PETSC_MIN_INT; 266642c7897SToby Isaac PetscInt minNc,maxNc; 267d092c84bSBrandon Whitchurch 268d092c84bSBrandon Whitchurch PetscFunctionBegin; 269d092c84bSBrandon Whitchurch if (sum->setupCalled) PetscFunctionReturn(0); 270d092c84bSBrandon Whitchurch 271*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetNumVariables(sp,&Nv)); 272*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetNumComponents(sp,&Nc)); 273*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSumGetNumSubspaces(sp,&Ns)); 274d092c84bSBrandon Whitchurch if (Ns == PETSC_DEFAULT) { 275d092c84bSBrandon Whitchurch Ns = 1; 276*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSumSetNumSubspaces(sp,Ns)); 277d092c84bSBrandon Whitchurch } 2782c71b3e2SJacob Faibussowitsch PetscCheckFalse(Ns < 0,PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Cannot have %D subspaces", Ns); 279642c7897SToby Isaac uniform = PETSC_TRUE; 280642c7897SToby Isaac if (Ns) { 281642c7897SToby Isaac PetscSpace s0; 282d092c84bSBrandon Whitchurch 283*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSumGetSubspace(sp,0,&s0)); 284642c7897SToby Isaac for (PetscInt i = 1; i < Ns; i++) { 285642c7897SToby Isaac PetscSpace si; 286642c7897SToby Isaac 287*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSumGetSubspace(sp,i,&si)); 288642c7897SToby Isaac if (si != s0) { 289642c7897SToby Isaac uniform = PETSC_FALSE; 290642c7897SToby Isaac break; 291642c7897SToby Isaac } 292642c7897SToby Isaac } 293642c7897SToby Isaac } 294642c7897SToby Isaac 295642c7897SToby Isaac minNc = Nc; 296642c7897SToby Isaac maxNc = Nc; 297d092c84bSBrandon Whitchurch for (i=0; i<Ns; ++i) { 298d092c84bSBrandon Whitchurch PetscInt sNv,sNc,iDeg,iMaxDeg; 299d092c84bSBrandon Whitchurch PetscSpace si; 300d092c84bSBrandon Whitchurch 301*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSumGetSubspace(sp,i,&si)); 302*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetUp(si)); 303*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetNumVariables(si,&sNv)); 3042c71b3e2SJacob Faibussowitsch PetscCheckFalse(sNv != Nv,PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_WRONGSTATE,"Subspace %D has %D variables, space has %D.",i,sNv,Nv); 305*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetNumComponents(si,&sNc)); 306d092c84bSBrandon Whitchurch if (i == 0 && sNc == Nc) concatenate = PETSC_FALSE; 307642c7897SToby Isaac minNc = PetscMin(minNc, sNc); 308642c7897SToby Isaac maxNc = PetscMax(maxNc, sNc); 309d092c84bSBrandon Whitchurch sum_Nc += sNc; 310*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSumGetSubspace(sp,i,&si)); 311*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetDegree(si,&iDeg,&iMaxDeg)); 312642c7897SToby Isaac deg = PetscMin(deg,iDeg); 313d092c84bSBrandon Whitchurch maxDeg = PetscMax(maxDeg,iMaxDeg); 314d092c84bSBrandon Whitchurch } 315d092c84bSBrandon Whitchurch 316d092c84bSBrandon Whitchurch if (concatenate) { 317d092c84bSBrandon Whitchurch if (sum_Nc != Nc) { 31898921bdaSJacob 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); 319d092c84bSBrandon Whitchurch } 320d092c84bSBrandon Whitchurch } else { 3212c71b3e2SJacob Faibussowitsch PetscCheckFalse(minNc != Nc || maxNc != Nc,PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Subspaces must have same number of components as the target space."); 322d092c84bSBrandon Whitchurch } 323d092c84bSBrandon Whitchurch 324d092c84bSBrandon Whitchurch sp->degree = deg; 325d092c84bSBrandon Whitchurch sp->maxDegree = maxDeg; 326d092c84bSBrandon Whitchurch sum->concatenate = concatenate; 327642c7897SToby Isaac sum->uniform = uniform; 328d092c84bSBrandon Whitchurch sum->setupCalled = PETSC_TRUE; 329d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 330d092c84bSBrandon Whitchurch } 331d092c84bSBrandon Whitchurch 332d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceSumView_Ascii(PetscSpace sp,PetscViewer v) 333d092c84bSBrandon Whitchurch { 334d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 335d092c84bSBrandon Whitchurch PetscBool concatenate = sum->concatenate; 336d092c84bSBrandon Whitchurch PetscInt i,Ns = sum->numSumSpaces; 337d092c84bSBrandon Whitchurch 338d092c84bSBrandon Whitchurch PetscFunctionBegin; 339d092c84bSBrandon Whitchurch if (concatenate) { 340*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(v,"Sum space of %D concatenated subspaces%s\n",Ns, sum->uniform ? " (all identical)": "")); 341d092c84bSBrandon Whitchurch } else { 342*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(v,"Sum space of %D subspaces%s\n",Ns, sum->uniform ? " (all identical)" : "")); 343d092c84bSBrandon Whitchurch } 344642c7897SToby Isaac for (i=0; i < (sum->uniform ? (Ns > 0 ? 1 : 0) : Ns); ++i) { 345*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPushTab(v)); 346*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceView(sum->sumspaces[i],v)); 347*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPopTab(v)); 348d092c84bSBrandon Whitchurch } 349d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 350d092c84bSBrandon Whitchurch } 351d092c84bSBrandon Whitchurch 352d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceView_Sum(PetscSpace sp,PetscViewer viewer) 353d092c84bSBrandon Whitchurch { 354d092c84bSBrandon Whitchurch PetscBool iascii; 355d092c84bSBrandon Whitchurch 356d092c84bSBrandon Whitchurch PetscFunctionBegin; 357*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 358d092c84bSBrandon Whitchurch if (iascii) { 359*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSumView_Ascii(sp,viewer)); 360d092c84bSBrandon Whitchurch } 361d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 362d092c84bSBrandon Whitchurch } 363d092c84bSBrandon Whitchurch 364d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceDestroy_Sum(PetscSpace sp) 365d092c84bSBrandon Whitchurch { 366d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 367d092c84bSBrandon Whitchurch PetscInt i,Ns = sum->numSumSpaces; 368d092c84bSBrandon Whitchurch 369d092c84bSBrandon Whitchurch PetscFunctionBegin; 370d092c84bSBrandon Whitchurch for (i=0; i<Ns; ++i) { 371*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceDestroy(&sum->sumspaces[i])); 372d092c84bSBrandon Whitchurch } 373*5f80ce2aSJacob Faibussowitsch CHKERRQ(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 */ 379642c7897SToby Isaac for (d = 0; d < sp->Nv; ++d) { 380*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceDestroy(&sum->heightsubspaces[d])); 381642c7897SToby Isaac } 382642c7897SToby Isaac } 383*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(sum->heightsubspaces)); 384*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetSubspace_C",NULL)); 385*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetSubspace_C",NULL)); 386*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetNumSubspaces_C",NULL)); 387*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetNumSubspaces_C",NULL)); 388*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(sum)); 389d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 390d092c84bSBrandon Whitchurch } 391d092c84bSBrandon Whitchurch 392d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceGetDimension_Sum(PetscSpace sp,PetscInt *dim) 393d092c84bSBrandon Whitchurch { 394d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 395d092c84bSBrandon Whitchurch PetscInt i,d = 0,Ns = sum->numSumSpaces; 396d092c84bSBrandon Whitchurch 397d092c84bSBrandon Whitchurch PetscFunctionBegin; 398642c7897SToby Isaac if (!sum->setupCalled) { 399*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetUp(sp)); 400*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetDimension(sp, dim)); 401642c7897SToby Isaac PetscFunctionReturn(0); 402642c7897SToby Isaac } 403d092c84bSBrandon Whitchurch 404d092c84bSBrandon Whitchurch for (i=0; i<Ns; ++i) { 405d092c84bSBrandon Whitchurch PetscInt id; 406d092c84bSBrandon Whitchurch 407*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetDimension(sum->sumspaces[i],&id)); 408d092c84bSBrandon Whitchurch d += id; 409d092c84bSBrandon Whitchurch } 410d092c84bSBrandon Whitchurch 411d092c84bSBrandon Whitchurch *dim = d; 412d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 413d092c84bSBrandon Whitchurch } 414d092c84bSBrandon Whitchurch 415d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceEvaluate_Sum(PetscSpace sp,PetscInt npoints,const PetscReal points[],PetscReal B[],PetscReal D[],PetscReal H[]) 416d092c84bSBrandon Whitchurch { 417d092c84bSBrandon Whitchurch PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 418d092c84bSBrandon Whitchurch PetscBool concatenate = sum->concatenate; 419d092c84bSBrandon Whitchurch DM dm = sp->dm; 420d092c84bSBrandon Whitchurch PetscInt Nc = sp->Nc,Nv = sp->Nv,Ns = sum->numSumSpaces; 421d092c84bSBrandon Whitchurch PetscInt i,s,offset,ncoffset,pdimfull,numelB,numelD,numelH; 422d092c84bSBrandon Whitchurch PetscReal *sB = NULL,*sD = NULL,*sH = NULL; 423d092c84bSBrandon Whitchurch 424d092c84bSBrandon Whitchurch PetscFunctionBegin; 425d092c84bSBrandon Whitchurch if (!sum->setupCalled) { 426*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetUp(sp)); 427*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceEvaluate(sp, npoints, points, B, D, H)); 428642c7897SToby Isaac PetscFunctionReturn(0); 429d092c84bSBrandon Whitchurch } 430*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetDimension(sp,&pdimfull)); 431d092c84bSBrandon Whitchurch numelB = npoints*pdimfull*Nc; 432d092c84bSBrandon Whitchurch numelD = numelB*Nv; 433d092c84bSBrandon Whitchurch numelH = numelD*Nv; 434d092c84bSBrandon Whitchurch if (B || D || H) { 435*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetWorkArray(dm,numelB,MPIU_REAL,&sB)); 436d092c84bSBrandon Whitchurch } 437d092c84bSBrandon Whitchurch if (D || H) { 438*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetWorkArray(dm,numelD,MPIU_REAL,&sD)); 439d092c84bSBrandon Whitchurch } 440d092c84bSBrandon Whitchurch if (H) { 441*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetWorkArray(dm,numelH,MPIU_REAL,&sH)); 442d092c84bSBrandon Whitchurch } 443d092c84bSBrandon Whitchurch if (B) 444d092c84bSBrandon Whitchurch for (i=0; i<numelB; ++i) B[i] = 0.; 445d092c84bSBrandon Whitchurch if (D) 446d092c84bSBrandon Whitchurch for (i=0; i<numelD; ++i) D[i] = 0.; 447d092c84bSBrandon Whitchurch if (H) 448d092c84bSBrandon Whitchurch for (i=0; i<numelH; ++i) H[i] = 0.; 449d092c84bSBrandon Whitchurch 450d092c84bSBrandon Whitchurch for (s=0,offset=0,ncoffset=0; s<Ns; ++s) { 451d092c84bSBrandon Whitchurch PetscInt sNv,spdim,sNc,p; 452d092c84bSBrandon Whitchurch 453*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetNumVariables(sum->sumspaces[s],&sNv)); 454*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetNumComponents(sum->sumspaces[s],&sNc)); 455*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetDimension(sum->sumspaces[s],&spdim)); 4562c71b3e2SJacob Faibussowitsch PetscCheckFalse(offset + spdim > pdimfull,PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Subspace dimensions exceed target space dimension."); 457642c7897SToby Isaac if (s == 0 || !sum->uniform) { 458*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceEvaluate(sum->sumspaces[s],npoints,points,sB,sD,sH)); 459642c7897SToby Isaac } 460d092c84bSBrandon Whitchurch if (B || D || H) { 461d092c84bSBrandon Whitchurch for (p=0; p<npoints; ++p) { 462d092c84bSBrandon Whitchurch PetscInt j; 463d092c84bSBrandon Whitchurch 464d092c84bSBrandon Whitchurch for (j=0; j<spdim; ++j) { 465d092c84bSBrandon Whitchurch PetscInt c; 466d092c84bSBrandon Whitchurch 467d092c84bSBrandon Whitchurch for (c=0; c<sNc; ++c) { 468d092c84bSBrandon Whitchurch PetscInt compoffset,BInd,sBInd; 469d092c84bSBrandon Whitchurch 470d092c84bSBrandon Whitchurch compoffset = concatenate ? c+ncoffset : c; 471d092c84bSBrandon Whitchurch BInd = (p*pdimfull + j + offset)*Nc + compoffset; 472d092c84bSBrandon Whitchurch sBInd = (p*spdim + j)*sNc + c; 473642c7897SToby Isaac if (B) B[BInd] = sB[sBInd]; 474d092c84bSBrandon Whitchurch if (D || H) { 475d092c84bSBrandon Whitchurch PetscInt v; 476d092c84bSBrandon Whitchurch 477d092c84bSBrandon Whitchurch for (v=0; v<Nv; ++v) { 478d092c84bSBrandon Whitchurch PetscInt DInd,sDInd; 479d092c84bSBrandon Whitchurch 480d092c84bSBrandon Whitchurch DInd = BInd*Nv + v; 481d092c84bSBrandon Whitchurch sDInd = sBInd*Nv + v; 482642c7897SToby Isaac if (D) D[DInd] = sD[sDInd]; 483d092c84bSBrandon Whitchurch if (H) { 484d092c84bSBrandon Whitchurch PetscInt v2; 485d092c84bSBrandon Whitchurch 486d092c84bSBrandon Whitchurch for (v2=0; v2<Nv; ++v2) { 487d092c84bSBrandon Whitchurch PetscInt HInd,sHInd; 488d092c84bSBrandon Whitchurch 489d092c84bSBrandon Whitchurch HInd = DInd*Nv + v2; 490d092c84bSBrandon Whitchurch sHInd = sDInd*Nv + v2; 491642c7897SToby Isaac H[HInd] = sH[sHInd]; 492d092c84bSBrandon Whitchurch } 493d092c84bSBrandon Whitchurch } 494d092c84bSBrandon Whitchurch } 495d092c84bSBrandon Whitchurch } 496d092c84bSBrandon Whitchurch } 497d092c84bSBrandon Whitchurch } 498d092c84bSBrandon Whitchurch } 499d092c84bSBrandon Whitchurch } 500d092c84bSBrandon Whitchurch offset += spdim; 501d092c84bSBrandon Whitchurch ncoffset += sNc; 502d092c84bSBrandon Whitchurch } 503d092c84bSBrandon Whitchurch 504d092c84bSBrandon Whitchurch if (H) { 505*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreWorkArray(dm,numelH,MPIU_REAL,&sH)); 506d092c84bSBrandon Whitchurch } 507d092c84bSBrandon Whitchurch if (D || H) { 508*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreWorkArray(dm,numelD,MPIU_REAL,&sD)); 509d092c84bSBrandon Whitchurch } 510d092c84bSBrandon Whitchurch if (B || D || H) { 511*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreWorkArray(dm,numelB,MPIU_REAL,&sB)); 512d092c84bSBrandon Whitchurch } 513d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 514d092c84bSBrandon Whitchurch } 515d092c84bSBrandon Whitchurch 516642c7897SToby Isaac static PetscErrorCode PetscSpaceGetHeightSubspace_Sum(PetscSpace sp, PetscInt height, PetscSpace *subsp) 517642c7897SToby Isaac { 518642c7897SToby Isaac PetscSpace_Sum *sum = (PetscSpace_Sum *) sp->data; 519642c7897SToby Isaac PetscInt Nc, dim, order; 520642c7897SToby Isaac PetscBool tensor; 521642c7897SToby Isaac 522642c7897SToby Isaac PetscFunctionBegin; 523*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetNumComponents(sp, &Nc)); 524*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetNumVariables(sp, &dim)); 525*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetDegree(sp, &order, NULL)); 526*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpacePolynomialGetTensor(sp, &tensor)); 5272c71b3e2SJacob 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); 528*5f80ce2aSJacob Faibussowitsch if (!sum->heightsubspaces) CHKERRQ(PetscCalloc1(dim, &sum->heightsubspaces)); 529642c7897SToby Isaac if (height <= dim) { 530642c7897SToby Isaac if (!sum->heightsubspaces[height-1]) { 531642c7897SToby Isaac PetscSpace sub; 532642c7897SToby Isaac const char *name; 533642c7897SToby Isaac 534*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceCreate(PetscObjectComm((PetscObject) sp), &sub)); 535*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectGetName((PetscObject) sp, &name)); 536*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectSetName((PetscObject) sub, name)); 537*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetType(sub, PETSCSPACESUM)); 538*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSumSetNumSubspaces(sub, sum->numSumSpaces)); 539*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSumSetConcatenate(sub, sum->concatenate)); 540*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetNumComponents(sub, Nc)); 541*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetNumVariables(sub, dim-height)); 542642c7897SToby Isaac for (PetscInt i = 0; i < sum->numSumSpaces; i++) { 543642c7897SToby Isaac PetscSpace subh; 544642c7897SToby Isaac 545*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetHeightSubspace(sum->sumspaces[i], height, &subh)); 546*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSumSetSubspace(sub, i, subh)); 547642c7897SToby Isaac } 548*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetUp(sub)); 549642c7897SToby Isaac sum->heightsubspaces[height-1] = sub; 550642c7897SToby Isaac } 551642c7897SToby Isaac *subsp = sum->heightsubspaces[height-1]; 552642c7897SToby Isaac } else { 553642c7897SToby Isaac *subsp = NULL; 554642c7897SToby Isaac } 555642c7897SToby Isaac PetscFunctionReturn(0); 556642c7897SToby Isaac } 557642c7897SToby Isaac 558d092c84bSBrandon Whitchurch static PetscErrorCode PetscSpaceInitialize_Sum(PetscSpace sp) 559d092c84bSBrandon Whitchurch { 560d092c84bSBrandon Whitchurch PetscFunctionBegin; 561d092c84bSBrandon Whitchurch sp->ops->setfromoptions = PetscSpaceSetFromOptions_Sum; 562d092c84bSBrandon Whitchurch sp->ops->setup = PetscSpaceSetUp_Sum; 563d092c84bSBrandon Whitchurch sp->ops->view = PetscSpaceView_Sum; 564d092c84bSBrandon Whitchurch sp->ops->destroy = PetscSpaceDestroy_Sum; 565d092c84bSBrandon Whitchurch sp->ops->getdimension = PetscSpaceGetDimension_Sum; 566d092c84bSBrandon Whitchurch sp->ops->evaluate = PetscSpaceEvaluate_Sum; 567642c7897SToby Isaac sp->ops->getheightsubspace = PetscSpaceGetHeightSubspace_Sum; 568d092c84bSBrandon Whitchurch 569*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetNumSubspaces_C",PetscSpaceSumGetNumSubspaces_Sum)); 570*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetNumSubspaces_C",PetscSpaceSumSetNumSubspaces_Sum)); 571*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetSubspace_C",PetscSpaceSumGetSubspace_Sum)); 572*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetSubspace_C",PetscSpaceSumSetSubspace_Sum)); 573*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetConcatenate_C",PetscSpaceSumGetConcatenate_Sum)); 574*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetConcatenate_C",PetscSpaceSumSetConcatenate_Sum)); 575d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 576d092c84bSBrandon Whitchurch } 577d092c84bSBrandon Whitchurch 578d092c84bSBrandon Whitchurch /*MC 579d092c84bSBrandon Whitchurch PETSCSPACESUM = "sum" - A PetscSpace object that encapsulates a sum of subspaces. 580d092c84bSBrandon Whitchurch That sum can either be direct or concatenate a concatenation.For example if A and B are spaces each with 2 components, 581d092c84bSBrandon 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 582d092c84bSBrandon Whitchurch same number of variables. 583d092c84bSBrandon Whitchurch 584d092c84bSBrandon Whitchurch Level: intermediate 585d092c84bSBrandon Whitchurch 586d092c84bSBrandon Whitchurch .seealso: PetscSpaceType, PetscSpaceCreate(), PetscSpaceSetType() 587d092c84bSBrandon Whitchurch M*/ 588d092c84bSBrandon Whitchurch PETSC_EXTERN PetscErrorCode PetscSpaceCreate_Sum(PetscSpace sp) 589d092c84bSBrandon Whitchurch { 590d092c84bSBrandon Whitchurch PetscSpace_Sum *sum; 591d092c84bSBrandon Whitchurch 592d092c84bSBrandon Whitchurch PetscFunctionBegin; 593d092c84bSBrandon Whitchurch PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1); 594*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscNewLog(sp,&sum)); 595642c7897SToby Isaac sum->numSumSpaces = PETSC_DEFAULT; 596d092c84bSBrandon Whitchurch sp->data = sum; 597*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceInitialize_Sum(sp)); 598d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 599d092c84bSBrandon Whitchurch } 600d092c84bSBrandon Whitchurch 601d092c84bSBrandon Whitchurch PETSC_EXTERN PetscErrorCode PetscSpaceCreateSum(PetscInt numSubspaces,const PetscSpace subspaces[],PetscBool concatenate,PetscSpace *sumSpace) 602d092c84bSBrandon Whitchurch { 603d092c84bSBrandon Whitchurch PetscInt i,Nv,Nc = 0; 604d092c84bSBrandon Whitchurch 605d092c84bSBrandon Whitchurch PetscFunctionBegin; 606d092c84bSBrandon Whitchurch if (sumSpace) { 607*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceDestroy(sumSpace)); 608d092c84bSBrandon Whitchurch } 609*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceCreate(PetscObjectComm((PetscObject)subspaces[0]),sumSpace)); 610*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetType(*sumSpace,PETSCSPACESUM)); 611*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSumSetNumSubspaces(*sumSpace,numSubspaces)); 612*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSumSetConcatenate(*sumSpace,concatenate)); 613d092c84bSBrandon Whitchurch for (i=0; i<numSubspaces; ++i) { 614d092c84bSBrandon Whitchurch PetscInt sNc; 615d092c84bSBrandon Whitchurch 616*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSumSetSubspace(*sumSpace,i,subspaces[i])); 617*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetNumComponents(subspaces[i],&sNc)); 618d092c84bSBrandon Whitchurch if (concatenate) Nc += sNc; 619d092c84bSBrandon Whitchurch else Nc = sNc; 620d092c84bSBrandon Whitchurch } 621*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetNumVariables(subspaces[0],&Nv)); 622*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetNumComponents(*sumSpace,Nc)); 623*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetNumVariables(*sumSpace,Nv)); 624*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetUp(*sumSpace)); 625d092c84bSBrandon Whitchurch 626d092c84bSBrandon Whitchurch PetscFunctionReturn(0); 627d092c84bSBrandon Whitchurch } 628