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, 159 "Cannot change number of subspaces after setup called\n"); 160 if (numSumSpaces == Ns) PetscFunctionReturn(0); 161 if (Ns >= 0) { 162 PetscInt s; 163 for (s=0; s<Ns; ++s) { 164 ierr = PetscSpaceDestroy(&sum->sumspaces[s]);CHKERRQ(ierr); 165 } 166 ierr = PetscFree(sum->sumspaces);CHKERRQ(ierr); 167 } 168 169 Ns = sum->numSumSpaces = numSumSpaces; 170 ierr = PetscCalloc1(Ns,&sum->sumspaces);CHKERRQ(ierr); 171 PetscFunctionReturn(0); 172 } 173 174 static PetscErrorCode PetscSpaceSumGetConcatenate_Sum(PetscSpace sp,PetscBool *concatenate) 175 { 176 PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 177 178 PetscFunctionBegin; 179 *concatenate = sum->concatenate; 180 PetscFunctionReturn(0); 181 } 182 183 static PetscErrorCode PetscSpaceSumSetConcatenate_Sum(PetscSpace sp,PetscBool concatenate) 184 { 185 PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 186 187 PetscFunctionBegin; 188 if (sum->setupCalled) SETERRQ(PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_WRONGSTATE,"Cannot change space concatenation after setup called.\n"); 189 190 sum->concatenate = concatenate; 191 PetscFunctionReturn(0); 192 } 193 194 static PetscErrorCode PetscSpaceSumGetSubspace_Sum(PetscSpace space,PetscInt s,PetscSpace *subspace) 195 { 196 PetscSpace_Sum *sum = (PetscSpace_Sum*)space->data; 197 PetscInt Ns = sum->numSumSpaces; 198 199 PetscFunctionBegin; 200 if (Ns < 0) SETERRQ(PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_WRONGSTATE,"Must call PetscSpaceSumSetNumSubspaces() first\n"); 201 if (s<0 || s>=Ns) SETERRQ1 (PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_OUTOFRANGE,"Invalid subspace number %D\n",subspace); 202 203 *subspace = sum->sumspaces[s]; 204 PetscFunctionReturn(0); 205 } 206 207 static PetscErrorCode PetscSpaceSumSetSubspace_Sum(PetscSpace space,PetscInt s,PetscSpace subspace) 208 { 209 PetscSpace_Sum *sum = (PetscSpace_Sum*)space->data; 210 PetscInt Ns = sum->numSumSpaces; 211 PetscErrorCode ierr; 212 213 PetscFunctionBegin; 214 if (sum->setupCalled) SETERRQ(PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_WRONGSTATE,"Cannot change subspace after setup called\n"); 215 if (Ns < 0) SETERRQ(PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_WRONGSTATE,"Must call PetscSpaceSumSetNumSubspaces() first\n"); 216 if (s < 0 || s >= Ns) SETERRQ1(PetscObjectComm((PetscObject)space),PETSC_ERR_ARG_OUTOFRANGE,"Invalid subspace number %D\n",subspace); 217 218 ierr = PetscObjectReference((PetscObject)subspace);CHKERRQ(ierr); 219 ierr = PetscSpaceDestroy(&sum->sumspaces[s]);CHKERRQ(ierr); 220 sum->sumspaces[s] = subspace; 221 PetscFunctionReturn(0); 222 } 223 224 static PetscErrorCode PetscSpaceSetFromOptions_Sum(PetscOptionItems *PetscOptionsObject,PetscSpace sp) 225 { 226 PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 227 PetscInt Ns,Nc,Nv,deg,i; 228 PetscBool concatenate = PETSC_TRUE; 229 const char *prefix; 230 PetscErrorCode ierr; 231 232 PetscFunctionBegin; 233 ierr = PetscSpaceGetNumVariables(sp,&Nv);CHKERRQ(ierr); 234 if (!Nv) PetscFunctionReturn(0); 235 ierr = PetscSpaceGetNumComponents(sp,&Nc);CHKERRQ(ierr); 236 ierr = PetscSpaceSumGetNumSubspaces(sp,&Ns);CHKERRQ(ierr); 237 ierr = PetscSpaceGetDegree(sp,°,NULL);CHKERRQ(ierr); 238 Ns = (Ns == PETSC_DEFAULT) ? 1 : Ns; 239 240 ierr = PetscOptionsHead(PetscOptionsObject,"PetscSpace sum options");CHKERRQ(ierr); 241 ierr = PetscOptionsBoundedInt("-petscspace_sum_spaces","The number of subspaces","PetscSpaceSumSetNumSubspaces",Ns,&Ns,NULL,0);CHKERRQ(ierr); 242 ierr = PetscOptionsBool("-petscspace_sum_concatenate","Subspaces are concatenated components of the final space","PetscSpaceSumSetFromOptions", 243 concatenate,&concatenate,NULL);CHKERRQ(ierr); 244 ierr = PetscOptionsTail();CHKERRQ(ierr); 245 246 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 if (Ns != sum->numSumSpaces) { 248 ierr = PetscSpaceSumSetNumSubspaces(sp,Ns);CHKERRQ(ierr); 249 } 250 ierr = PetscObjectGetOptionsPrefix((PetscObject)sp,&prefix);CHKERRQ(ierr); 251 for (i=0; i<Ns; ++i) { 252 PetscInt sNv; 253 PetscSpace subspace; 254 255 ierr = PetscSpaceSumGetSubspace(sp,i,&subspace);CHKERRQ(ierr); 256 if (!subspace) { 257 char subspacePrefix[256]; 258 259 ierr = PetscSpaceCreate(PetscObjectComm((PetscObject)sp),&subspace);CHKERRQ(ierr); 260 ierr = PetscObjectSetOptionsPrefix((PetscObject)subspace,prefix);CHKERRQ(ierr); 261 ierr = PetscSNPrintf(subspacePrefix,256,"subspace%d_",i);CHKERRQ(ierr); 262 ierr = PetscObjectAppendOptionsPrefix((PetscObject)subspace,subspacePrefix);CHKERRQ(ierr); 263 } else { 264 ierr = PetscObjectReference((PetscObject)subspace);CHKERRQ(ierr); 265 } 266 ierr = PetscSpaceSetFromOptions(subspace);CHKERRQ(ierr); 267 ierr = PetscSpaceGetNumVariables(subspace,&sNv);CHKERRQ(ierr); 268 if (!sNv) SETERRQ1(PetscObjectComm( 269 (PetscObject)sp),PETSC_ERR_ARG_WRONGSTATE,"Subspace %D has not been set properly, number of variables is 0.\n",i); 270 ierr = PetscSpaceSumSetSubspace(sp,i,subspace);CHKERRQ(ierr); 271 ierr = PetscSpaceDestroy(&subspace);CHKERRQ(ierr); 272 } 273 PetscFunctionReturn(0); 274 } 275 276 static PetscErrorCode PetscSpaceSetUp_Sum(PetscSpace sp) 277 { 278 PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 279 PetscBool concatenate = PETSC_TRUE; 280 PetscInt Nv,Ns,Nc,i,sum_Nc = 0,deg = PETSC_MIN_INT,maxDeg = PETSC_MIN_INT; 281 PetscErrorCode ierr; 282 283 PetscFunctionBegin; 284 if (sum->setupCalled) PetscFunctionReturn(0); 285 286 ierr = PetscSpaceGetNumVariables(sp,&Nv);CHKERRQ(ierr); 287 ierr = PetscSpaceGetNumComponents(sp,&Nc);CHKERRQ(ierr); 288 ierr = PetscSpaceSumGetNumSubspaces(sp,&Ns);CHKERRQ(ierr); 289 if (Ns == PETSC_DEFAULT) { 290 Ns = 1; 291 ierr = PetscSpaceSumSetNumSubspaces(sp,Ns);CHKERRQ(ierr); 292 } 293 if (!Ns && Nv) SETERRQ(PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Cannot have zero subspaces\n"); 294 295 for (i=0; i<Ns; ++i) { 296 PetscInt sNv,sNc,iDeg,iMaxDeg; 297 PetscSpace si; 298 299 ierr = PetscSpaceSumGetSubspace(sp,i,&si);CHKERRQ(ierr); 300 ierr = PetscSpaceSetUp(si);CHKERRQ(ierr); 301 ierr = PetscSpaceGetNumVariables(si,&sNv);CHKERRQ(ierr); 302 if (sNv != Nv) SETERRQ3(PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_WRONGSTATE,"Subspace %D has %D variables, space has %D.\n",i,sNv,Nv); 303 ierr = PetscSpaceGetNumComponents(si,&sNc);CHKERRQ(ierr); 304 if (i == 0 && sNc == Nc) concatenate = PETSC_FALSE; 305 sum_Nc += sNc; 306 ierr = PetscSpaceSumGetSubspace(sp,i,&si);CHKERRQ(ierr); 307 ierr = PetscSpaceGetDegree(si,&iDeg,&iMaxDeg);CHKERRQ(ierr); 308 deg = PetscMax(deg,iDeg); 309 maxDeg = PetscMax(maxDeg,iMaxDeg); 310 } 311 312 if (concatenate) { 313 if (sum_Nc != Nc) { 314 SETERRQ2(PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE, 315 "Total number of subspace components (%D) does not match number of target space components (%D).",sum_Nc,Nc); 316 } 317 } else { 318 if (sum_Nc != Ns*Nc) SETERRQ(PetscObjectComm( 319 (PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Subspaces must have same number of components as the target space."); 320 } 321 322 sp->degree = deg; 323 sp->maxDegree = maxDeg; 324 sum->concatenate = concatenate; 325 sum->setupCalled = PETSC_TRUE; 326 PetscFunctionReturn(0); 327 } 328 329 static PetscErrorCode PetscSpaceSumView_Ascii(PetscSpace sp,PetscViewer v) 330 { 331 PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 332 PetscBool concatenate = sum->concatenate; 333 PetscInt i,Ns = sum->numSumSpaces; 334 PetscErrorCode ierr; 335 336 PetscFunctionBegin; 337 if (concatenate) { 338 ierr = PetscViewerASCIIPrintf(v,"Sum space of %D concatenated subspaces\n",Ns);CHKERRQ(ierr); 339 } else { 340 ierr = PetscViewerASCIIPrintf(v,"Sum space of %D subspaces\n",Ns);CHKERRQ(ierr); 341 } 342 for (i=0; i<Ns; ++i) { 343 ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr); 344 ierr = PetscSpaceView(sum->sumspaces[i],v);CHKERRQ(ierr); 345 ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr); 346 } 347 PetscFunctionReturn(0); 348 } 349 350 static PetscErrorCode PetscSpaceView_Sum(PetscSpace sp,PetscViewer viewer) 351 { 352 PetscBool iascii; 353 PetscErrorCode ierr; 354 355 PetscFunctionBegin; 356 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 357 if (iascii) { 358 ierr = PetscSpaceSumView_Ascii(sp,viewer);CHKERRQ(ierr); 359 } 360 PetscFunctionReturn(0); 361 } 362 363 static PetscErrorCode PetscSpaceDestroy_Sum(PetscSpace sp) 364 { 365 PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 366 PetscInt i,Ns = sum->numSumSpaces; 367 PetscErrorCode ierr; 368 369 PetscFunctionBegin; 370 for (i=0; i<Ns; ++i) { 371 ierr = PetscSpaceDestroy(&sum->sumspaces[i]);CHKERRQ(ierr); 372 } 373 ierr = PetscFree(sum->sumspaces);CHKERRQ(ierr); 374 ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetSubspace_C",NULL);CHKERRQ(ierr); 375 ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetSubspace_C",NULL);CHKERRQ(ierr); 376 ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetNumSubspaces_C",NULL);CHKERRQ(ierr); 377 ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetNumSubspaces_C",NULL);CHKERRQ(ierr); 378 ierr = PetscFree(sum);CHKERRQ(ierr); 379 PetscFunctionReturn(0); 380 } 381 382 static PetscErrorCode PetscSpaceGetDimension_Sum(PetscSpace sp,PetscInt *dim) 383 { 384 PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 385 PetscInt i,d = 0,Ns = sum->numSumSpaces; 386 PetscErrorCode ierr; 387 388 PetscFunctionBegin; 389 ierr = PetscSpaceSetUp(sp);CHKERRQ(ierr); 390 391 for (i=0; i<Ns; ++i) { 392 PetscInt id; 393 394 ierr = PetscSpaceGetDimension(sum->sumspaces[i],&id);CHKERRQ(ierr); 395 d += id; 396 } 397 398 *dim = d; 399 PetscFunctionReturn(0); 400 } 401 402 static PetscErrorCode PetscSpaceEvaluate_Sum(PetscSpace sp,PetscInt npoints,const PetscReal points[],PetscReal B[],PetscReal D[],PetscReal H[]) 403 { 404 PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 405 PetscBool concatenate = sum->concatenate; 406 DM dm = sp->dm; 407 PetscInt Nc = sp->Nc,Nv = sp->Nv,Ns = sum->numSumSpaces; 408 PetscInt i,s,offset,ncoffset,pdimfull,numelB,numelD,numelH; 409 PetscReal *sB = NULL,*sD = NULL,*sH = NULL; 410 PetscErrorCode ierr; 411 412 PetscFunctionBegin; 413 if (!sum->setupCalled) { 414 ierr = PetscSpaceSetUp(sp);CHKERRQ(ierr); 415 } 416 ierr = PetscSpaceGetDimension(sp,&pdimfull);CHKERRQ(ierr); 417 numelB = npoints*pdimfull*Nc; 418 numelD = numelB*Nv; 419 numelH = numelD*Nv; 420 if (B || D || H) { 421 ierr = DMGetWorkArray(dm,numelB,MPIU_REAL,&sB);CHKERRQ(ierr); 422 } 423 if (D || H) { 424 ierr = DMGetWorkArray(dm,numelD,MPIU_REAL,&sD);CHKERRQ(ierr); 425 } 426 if (H) { 427 ierr = DMGetWorkArray(dm,numelH,MPIU_REAL,&sH);CHKERRQ(ierr); 428 } 429 if (B) 430 for (i=0; i<numelB; ++i) B[i] = 0.; 431 if (D) 432 for (i=0; i<numelD; ++i) D[i] = 0.; 433 if (H) 434 for (i=0; i<numelH; ++i) H[i] = 0.; 435 436 for (s=0,offset=0,ncoffset=0; s<Ns; ++s) { 437 PetscInt sNv,spdim,sNc,p; 438 439 ierr = PetscSpaceGetNumVariables(sum->sumspaces[s],&sNv);CHKERRQ(ierr); 440 ierr = PetscSpaceGetNumComponents(sum->sumspaces[s],&sNc);CHKERRQ(ierr); 441 ierr = PetscSpaceGetDimension(sum->sumspaces[s],&spdim);CHKERRQ(ierr); 442 if (offset + spdim > pdimfull) SETERRQ(PetscObjectComm( 443 (PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Subspace dimensions exceed target space dimension.\n"); 444 ierr = PetscSpaceEvaluate(sum->sumspaces[s],npoints,points,sB,sD,sH);CHKERRQ(ierr); 445 if (B || D || H) { 446 for (p=0; p<npoints; ++p) { 447 PetscInt j; 448 449 for (j=0; j<spdim; ++j) { 450 PetscInt c; 451 452 for (c=0; c<sNc; ++c) { 453 PetscInt compoffset,BInd,sBInd; 454 455 compoffset = concatenate ? c+ncoffset : c; 456 BInd = (p*pdimfull + j + offset)*Nc + compoffset; 457 sBInd = (p*spdim + j)*sNc + c; 458 if (B) B[BInd] += sB[sBInd]; 459 if (D || H) { 460 PetscInt v; 461 462 for (v=0; v<Nv; ++v) { 463 PetscInt DInd,sDInd; 464 465 DInd = BInd*Nv + v; 466 sDInd = sBInd*Nv + v; 467 if (D) D[DInd] +=sD[sDInd]; 468 if (H) { 469 PetscInt v2; 470 471 for (v2=0; v2<Nv; ++v2) { 472 PetscInt HInd,sHInd; 473 474 HInd = DInd*Nv + v2; 475 sHInd = sDInd*Nv + v2; 476 H[HInd] += sH[sHInd]; 477 } 478 } 479 } 480 } 481 } 482 } 483 } 484 } 485 offset += spdim; 486 ncoffset += sNc; 487 } 488 489 if (H) { 490 ierr = DMRestoreWorkArray(dm,numelH,MPIU_REAL,&sH);CHKERRQ(ierr); 491 } 492 if (D || H) { 493 ierr = DMRestoreWorkArray(dm,numelD,MPIU_REAL,&sD);CHKERRQ(ierr); 494 } 495 if (B || D || H) { 496 ierr = DMRestoreWorkArray(dm,numelB,MPIU_REAL,&sB);CHKERRQ(ierr); 497 } 498 PetscFunctionReturn(0); 499 } 500 501 static PetscErrorCode PetscSpaceInitialize_Sum(PetscSpace sp) 502 { 503 PetscErrorCode ierr; 504 505 PetscFunctionBegin; 506 sp->ops->setfromoptions = PetscSpaceSetFromOptions_Sum; 507 sp->ops->setup = PetscSpaceSetUp_Sum; 508 sp->ops->view = PetscSpaceView_Sum; 509 sp->ops->destroy = PetscSpaceDestroy_Sum; 510 sp->ops->getdimension = PetscSpaceGetDimension_Sum; 511 sp->ops->evaluate = PetscSpaceEvaluate_Sum; 512 513 ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetNumSubspaces_C",PetscSpaceSumGetNumSubspaces_Sum);CHKERRQ(ierr); 514 ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetNumSubspaces_C",PetscSpaceSumSetNumSubspaces_Sum);CHKERRQ(ierr); 515 ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetSubspace_C",PetscSpaceSumGetSubspace_Sum);CHKERRQ(ierr); 516 ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetSubspace_C",PetscSpaceSumSetSubspace_Sum);CHKERRQ(ierr); 517 ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetConcatenate_C",PetscSpaceSumGetConcatenate_Sum);CHKERRQ(ierr); 518 ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetConcatenate_C",PetscSpaceSumSetConcatenate_Sum);CHKERRQ(ierr); 519 PetscFunctionReturn(0); 520 } 521 522 /*MC 523 PETSCSPACESUM = "sum" - A PetscSpace object that encapsulates a sum of subspaces. 524 That sum can either be direct or concatenate a concatenation.For example if A and B are spaces each with 2 components, 525 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 same number of variables. 527 528 Level: intermediate 529 530 .seealso: PetscSpaceType, PetscSpaceCreate(), PetscSpaceSetType() 531 M*/ 532 PETSC_EXTERN PetscErrorCode PetscSpaceCreate_Sum(PetscSpace sp) 533 { 534 PetscSpace_Sum *sum; 535 PetscErrorCode ierr; 536 537 PetscFunctionBegin; 538 PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1); 539 ierr = PetscNewLog(sp,&sum);CHKERRQ(ierr); 540 sp->data = sum; 541 ierr = PetscSpaceInitialize_Sum(sp);CHKERRQ(ierr); 542 PetscFunctionReturn(0); 543 } 544 545 PETSC_EXTERN PetscErrorCode PetscSpaceCreateSum(PetscInt numSubspaces,const PetscSpace subspaces[],PetscBool concatenate,PetscSpace *sumSpace) 546 { 547 PetscInt i,Nv,Nc = 0; 548 PetscErrorCode ierr; 549 550 PetscFunctionBegin; 551 if (sumSpace) { 552 ierr = PetscSpaceDestroy(sumSpace);CHKERRQ(ierr); 553 } 554 ierr = PetscSpaceCreate(PetscObjectComm((PetscObject)subspaces[0]),sumSpace);CHKERRQ(ierr); 555 ierr = PetscSpaceSetType(*sumSpace,PETSCSPACESUM);CHKERRQ(ierr); 556 ierr = PetscSpaceSumSetNumSubspaces(*sumSpace,numSubspaces);CHKERRQ(ierr); 557 ierr = PetscSpaceSumSetConcatenate(*sumSpace,concatenate);CHKERRQ(ierr); 558 for (i=0; i<numSubspaces; ++i) { 559 PetscInt sNc; 560 561 ierr = PetscSpaceSumSetSubspace(*sumSpace,i,subspaces[i]);CHKERRQ(ierr); 562 ierr = PetscSpaceGetNumComponents(subspaces[i],&sNc);CHKERRQ(ierr); 563 if (concatenate) Nc += sNc; 564 else Nc = sNc; 565 } 566 ierr = PetscSpaceGetNumVariables(subspaces[0],&Nv);CHKERRQ(ierr); 567 ierr = PetscSpaceSetNumComponents(*sumSpace,Nc);CHKERRQ(ierr); 568 ierr = PetscSpaceSetNumVariables(*sumSpace,Nv);CHKERRQ(ierr); 569 ierr = PetscSpaceSetUp(*sumSpace);CHKERRQ(ierr); 570 571 PetscFunctionReturn(0); 572 } 573