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