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