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