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,"sumcomp_%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 PetscBool uniform; 279 PetscInt Nv,Ns,Nc,i,sum_Nc = 0,deg = PETSC_MAX_INT,maxDeg = PETSC_MIN_INT; 280 PetscInt minNc,maxNc; 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 < 0) SETERRQ1(PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Cannot have %D subspaces\n", Ns); 294 uniform = PETSC_TRUE; 295 if (Ns) { 296 PetscSpace s0; 297 298 ierr = PetscSpaceSumGetSubspace(sp,0,&s0);CHKERRQ(ierr); 299 for (PetscInt i = 1; i < Ns; i++) { 300 PetscSpace si; 301 302 ierr = PetscSpaceSumGetSubspace(sp,i,&si);CHKERRQ(ierr); 303 if (si != s0) { 304 uniform = PETSC_FALSE; 305 break; 306 } 307 } 308 } 309 310 minNc = Nc; 311 maxNc = Nc; 312 for (i=0; i<Ns; ++i) { 313 PetscInt sNv,sNc,iDeg,iMaxDeg; 314 PetscSpace si; 315 316 ierr = PetscSpaceSumGetSubspace(sp,i,&si);CHKERRQ(ierr); 317 ierr = PetscSpaceSetUp(si);CHKERRQ(ierr); 318 ierr = PetscSpaceGetNumVariables(si,&sNv);CHKERRQ(ierr); 319 if (sNv != Nv) SETERRQ3(PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_WRONGSTATE,"Subspace %D has %D variables, space has %D.\n",i,sNv,Nv); 320 ierr = PetscSpaceGetNumComponents(si,&sNc);CHKERRQ(ierr); 321 if (i == 0 && sNc == Nc) concatenate = PETSC_FALSE; 322 minNc = PetscMin(minNc, sNc); 323 maxNc = PetscMax(maxNc, sNc); 324 sum_Nc += sNc; 325 ierr = PetscSpaceSumGetSubspace(sp,i,&si);CHKERRQ(ierr); 326 ierr = PetscSpaceGetDegree(si,&iDeg,&iMaxDeg);CHKERRQ(ierr); 327 deg = PetscMin(deg,iDeg); 328 maxDeg = PetscMax(maxDeg,iMaxDeg); 329 } 330 331 if (concatenate) { 332 if (sum_Nc != Nc) { 333 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); 334 } 335 } else { 336 if (minNc != Nc || maxNc != Nc) SETERRQ(PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Subspaces must have same number of components as the target space."); 337 } 338 339 sp->degree = deg; 340 sp->maxDegree = maxDeg; 341 sum->concatenate = concatenate; 342 sum->uniform = uniform; 343 sum->setupCalled = PETSC_TRUE; 344 PetscFunctionReturn(0); 345 } 346 347 static PetscErrorCode PetscSpaceSumView_Ascii(PetscSpace sp,PetscViewer v) 348 { 349 PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 350 PetscBool concatenate = sum->concatenate; 351 PetscInt i,Ns = sum->numSumSpaces; 352 PetscErrorCode ierr; 353 354 PetscFunctionBegin; 355 if (concatenate) { 356 ierr = PetscViewerASCIIPrintf(v,"Sum space of %D concatenated subspaces%s\n",Ns, sum->uniform ? " (all identical)": "");CHKERRQ(ierr); 357 } else { 358 ierr = PetscViewerASCIIPrintf(v,"Sum space of %D subspaces%s\n",Ns, sum->uniform ? " (all identical)" : "");CHKERRQ(ierr); 359 } 360 for (i=0; i < (sum->uniform ? (Ns > 0 ? 1 : 0) : Ns); ++i) { 361 ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr); 362 ierr = PetscSpaceView(sum->sumspaces[i],v);CHKERRQ(ierr); 363 ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr); 364 } 365 PetscFunctionReturn(0); 366 } 367 368 static PetscErrorCode PetscSpaceView_Sum(PetscSpace sp,PetscViewer viewer) 369 { 370 PetscBool iascii; 371 PetscErrorCode ierr; 372 373 PetscFunctionBegin; 374 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 375 if (iascii) { 376 ierr = PetscSpaceSumView_Ascii(sp,viewer);CHKERRQ(ierr); 377 } 378 PetscFunctionReturn(0); 379 } 380 381 static PetscErrorCode PetscSpaceDestroy_Sum(PetscSpace sp) 382 { 383 PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 384 PetscInt i,Ns = sum->numSumSpaces; 385 PetscErrorCode ierr; 386 387 PetscFunctionBegin; 388 for (i=0; i<Ns; ++i) { 389 ierr = PetscSpaceDestroy(&sum->sumspaces[i]);CHKERRQ(ierr); 390 } 391 ierr = PetscFree(sum->sumspaces);CHKERRQ(ierr); 392 if (sum->heightsubspaces) { 393 PetscInt d; 394 395 /* sp->Nv is the spatial dimension, so it is equal to the number 396 * of subspaces on higher co-dimension points */ 397 for (d = 0; d < sp->Nv; ++d) { 398 ierr = PetscSpaceDestroy(&sum->heightsubspaces[d]);CHKERRQ(ierr); 399 } 400 } 401 ierr = PetscFree(sum->heightsubspaces);CHKERRQ(ierr); 402 ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetSubspace_C",NULL);CHKERRQ(ierr); 403 ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetSubspace_C",NULL);CHKERRQ(ierr); 404 ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetNumSubspaces_C",NULL);CHKERRQ(ierr); 405 ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetNumSubspaces_C",NULL);CHKERRQ(ierr); 406 ierr = PetscFree(sum);CHKERRQ(ierr); 407 PetscFunctionReturn(0); 408 } 409 410 static PetscErrorCode PetscSpaceGetDimension_Sum(PetscSpace sp,PetscInt *dim) 411 { 412 PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 413 PetscInt i,d = 0,Ns = sum->numSumSpaces; 414 PetscErrorCode ierr; 415 416 PetscFunctionBegin; 417 if (!sum->setupCalled) { 418 ierr = PetscSpaceSetUp(sp);CHKERRQ(ierr); 419 ierr = PetscSpaceGetDimension(sp, dim);CHKERRQ(ierr); 420 PetscFunctionReturn(0); 421 } 422 423 for (i=0; i<Ns; ++i) { 424 PetscInt id; 425 426 ierr = PetscSpaceGetDimension(sum->sumspaces[i],&id);CHKERRQ(ierr); 427 d += id; 428 } 429 430 *dim = d; 431 PetscFunctionReturn(0); 432 } 433 434 static PetscErrorCode PetscSpaceEvaluate_Sum(PetscSpace sp,PetscInt npoints,const PetscReal points[],PetscReal B[],PetscReal D[],PetscReal H[]) 435 { 436 PetscSpace_Sum *sum = (PetscSpace_Sum*)sp->data; 437 PetscBool concatenate = sum->concatenate; 438 DM dm = sp->dm; 439 PetscInt Nc = sp->Nc,Nv = sp->Nv,Ns = sum->numSumSpaces; 440 PetscInt i,s,offset,ncoffset,pdimfull,numelB,numelD,numelH; 441 PetscReal *sB = NULL,*sD = NULL,*sH = NULL; 442 PetscErrorCode ierr; 443 444 PetscFunctionBegin; 445 if (!sum->setupCalled) { 446 ierr = PetscSpaceSetUp(sp);CHKERRQ(ierr); 447 ierr = PetscSpaceEvaluate(sp, npoints, points, B, D, H);CHKERRQ(ierr); 448 PetscFunctionReturn(0); 449 } 450 ierr = PetscSpaceGetDimension(sp,&pdimfull);CHKERRQ(ierr); 451 numelB = npoints*pdimfull*Nc; 452 numelD = numelB*Nv; 453 numelH = numelD*Nv; 454 if (B || D || H) { 455 ierr = DMGetWorkArray(dm,numelB,MPIU_REAL,&sB);CHKERRQ(ierr); 456 } 457 if (D || H) { 458 ierr = DMGetWorkArray(dm,numelD,MPIU_REAL,&sD);CHKERRQ(ierr); 459 } 460 if (H) { 461 ierr = DMGetWorkArray(dm,numelH,MPIU_REAL,&sH);CHKERRQ(ierr); 462 } 463 if (B) 464 for (i=0; i<numelB; ++i) B[i] = 0.; 465 if (D) 466 for (i=0; i<numelD; ++i) D[i] = 0.; 467 if (H) 468 for (i=0; i<numelH; ++i) H[i] = 0.; 469 470 for (s=0,offset=0,ncoffset=0; s<Ns; ++s) { 471 PetscInt sNv,spdim,sNc,p; 472 473 ierr = PetscSpaceGetNumVariables(sum->sumspaces[s],&sNv);CHKERRQ(ierr); 474 ierr = PetscSpaceGetNumComponents(sum->sumspaces[s],&sNc);CHKERRQ(ierr); 475 ierr = PetscSpaceGetDimension(sum->sumspaces[s],&spdim);CHKERRQ(ierr); 476 if (offset + spdim > pdimfull) SETERRQ(PetscObjectComm((PetscObject)sp),PETSC_ERR_ARG_OUTOFRANGE,"Subspace dimensions exceed target space dimension.\n"); 477 if (s == 0 || !sum->uniform) { 478 ierr = PetscSpaceEvaluate(sum->sumspaces[s],npoints,points,sB,sD,sH);CHKERRQ(ierr); 479 } 480 if (B || D || H) { 481 for (p=0; p<npoints; ++p) { 482 PetscInt j; 483 484 for (j=0; j<spdim; ++j) { 485 PetscInt c; 486 487 for (c=0; c<sNc; ++c) { 488 PetscInt compoffset,BInd,sBInd; 489 490 compoffset = concatenate ? c+ncoffset : c; 491 BInd = (p*pdimfull + j + offset)*Nc + compoffset; 492 sBInd = (p*spdim + j)*sNc + c; 493 if (B) B[BInd] = sB[sBInd]; 494 if (D || H) { 495 PetscInt v; 496 497 for (v=0; v<Nv; ++v) { 498 PetscInt DInd,sDInd; 499 500 DInd = BInd*Nv + v; 501 sDInd = sBInd*Nv + v; 502 if (D) D[DInd] = sD[sDInd]; 503 if (H) { 504 PetscInt v2; 505 506 for (v2=0; v2<Nv; ++v2) { 507 PetscInt HInd,sHInd; 508 509 HInd = DInd*Nv + v2; 510 sHInd = sDInd*Nv + v2; 511 H[HInd] = sH[sHInd]; 512 } 513 } 514 } 515 } 516 } 517 } 518 } 519 } 520 offset += spdim; 521 ncoffset += sNc; 522 } 523 524 if (H) { 525 ierr = DMRestoreWorkArray(dm,numelH,MPIU_REAL,&sH);CHKERRQ(ierr); 526 } 527 if (D || H) { 528 ierr = DMRestoreWorkArray(dm,numelD,MPIU_REAL,&sD);CHKERRQ(ierr); 529 } 530 if (B || D || H) { 531 ierr = DMRestoreWorkArray(dm,numelB,MPIU_REAL,&sB);CHKERRQ(ierr); 532 } 533 PetscFunctionReturn(0); 534 } 535 536 static PetscErrorCode PetscSpaceGetHeightSubspace_Sum(PetscSpace sp, PetscInt height, PetscSpace *subsp) 537 { 538 PetscSpace_Sum *sum = (PetscSpace_Sum *) sp->data; 539 PetscInt Nc, dim, order; 540 PetscBool tensor; 541 PetscErrorCode ierr; 542 543 PetscFunctionBegin; 544 ierr = PetscSpaceGetNumComponents(sp, &Nc);CHKERRQ(ierr); 545 ierr = PetscSpaceGetNumVariables(sp, &dim);CHKERRQ(ierr); 546 ierr = PetscSpaceGetDegree(sp, &order, NULL);CHKERRQ(ierr); 547 ierr = PetscSpacePolynomialGetTensor(sp, &tensor);CHKERRQ(ierr); 548 if (height > dim || height < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Asked for space at height %D for dimension %D space", height, dim); 549 if (!sum->heightsubspaces) {ierr = PetscCalloc1(dim, &sum->heightsubspaces);CHKERRQ(ierr);} 550 if (height <= dim) { 551 if (!sum->heightsubspaces[height-1]) { 552 PetscSpace sub; 553 const char *name; 554 555 ierr = PetscSpaceCreate(PetscObjectComm((PetscObject) sp), &sub);CHKERRQ(ierr); 556 ierr = PetscObjectGetName((PetscObject) sp, &name);CHKERRQ(ierr); 557 ierr = PetscObjectSetName((PetscObject) sub, name);CHKERRQ(ierr); 558 ierr = PetscSpaceSetType(sub, PETSCSPACESUM);CHKERRQ(ierr); 559 ierr = PetscSpaceSumSetNumSubspaces(sub, sum->numSumSpaces);CHKERRQ(ierr); 560 ierr = PetscSpaceSumSetConcatenate(sub, sum->concatenate);CHKERRQ(ierr); 561 ierr = PetscSpaceSetNumComponents(sub, Nc);CHKERRQ(ierr); 562 ierr = PetscSpaceSetNumVariables(sub, dim-height);CHKERRQ(ierr); 563 for (PetscInt i = 0; i < sum->numSumSpaces; i++) { 564 PetscSpace subh; 565 566 ierr = PetscSpaceGetHeightSubspace(sum->sumspaces[i], height, &subh);CHKERRQ(ierr); 567 ierr = PetscSpaceSumSetSubspace(sub, i, subh);CHKERRQ(ierr); 568 } 569 ierr = PetscSpaceSetUp(sub);CHKERRQ(ierr); 570 sum->heightsubspaces[height-1] = sub; 571 } 572 *subsp = sum->heightsubspaces[height-1]; 573 } else { 574 *subsp = NULL; 575 } 576 PetscFunctionReturn(0); 577 } 578 579 static PetscErrorCode PetscSpaceInitialize_Sum(PetscSpace sp) 580 { 581 PetscErrorCode ierr; 582 583 PetscFunctionBegin; 584 sp->ops->setfromoptions = PetscSpaceSetFromOptions_Sum; 585 sp->ops->setup = PetscSpaceSetUp_Sum; 586 sp->ops->view = PetscSpaceView_Sum; 587 sp->ops->destroy = PetscSpaceDestroy_Sum; 588 sp->ops->getdimension = PetscSpaceGetDimension_Sum; 589 sp->ops->evaluate = PetscSpaceEvaluate_Sum; 590 sp->ops->getheightsubspace = PetscSpaceGetHeightSubspace_Sum; 591 592 ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetNumSubspaces_C",PetscSpaceSumGetNumSubspaces_Sum);CHKERRQ(ierr); 593 ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetNumSubspaces_C",PetscSpaceSumSetNumSubspaces_Sum);CHKERRQ(ierr); 594 ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetSubspace_C",PetscSpaceSumGetSubspace_Sum);CHKERRQ(ierr); 595 ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetSubspace_C",PetscSpaceSumSetSubspace_Sum);CHKERRQ(ierr); 596 ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumGetConcatenate_C",PetscSpaceSumGetConcatenate_Sum);CHKERRQ(ierr); 597 ierr = PetscObjectComposeFunction((PetscObject)sp,"PetscSpaceSumSetConcatenate_C",PetscSpaceSumSetConcatenate_Sum);CHKERRQ(ierr); 598 PetscFunctionReturn(0); 599 } 600 601 /*MC 602 PETSCSPACESUM = "sum" - A PetscSpace object that encapsulates a sum of subspaces. 603 That sum can either be direct or concatenate a concatenation.For example if A and B are spaces each with 2 components, 604 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 605 same number of variables. 606 607 Level: intermediate 608 609 .seealso: PetscSpaceType, PetscSpaceCreate(), PetscSpaceSetType() 610 M*/ 611 PETSC_EXTERN PetscErrorCode PetscSpaceCreate_Sum(PetscSpace sp) 612 { 613 PetscSpace_Sum *sum; 614 PetscErrorCode ierr; 615 616 PetscFunctionBegin; 617 PetscValidHeaderSpecific(sp,PETSCSPACE_CLASSID,1); 618 ierr = PetscNewLog(sp,&sum);CHKERRQ(ierr); 619 sum->numSumSpaces = PETSC_DEFAULT; 620 sp->data = sum; 621 ierr = PetscSpaceInitialize_Sum(sp);CHKERRQ(ierr); 622 PetscFunctionReturn(0); 623 } 624 625 PETSC_EXTERN PetscErrorCode PetscSpaceCreateSum(PetscInt numSubspaces,const PetscSpace subspaces[],PetscBool concatenate,PetscSpace *sumSpace) 626 { 627 PetscInt i,Nv,Nc = 0; 628 PetscErrorCode ierr; 629 630 PetscFunctionBegin; 631 if (sumSpace) { 632 ierr = PetscSpaceDestroy(sumSpace);CHKERRQ(ierr); 633 } 634 ierr = PetscSpaceCreate(PetscObjectComm((PetscObject)subspaces[0]),sumSpace);CHKERRQ(ierr); 635 ierr = PetscSpaceSetType(*sumSpace,PETSCSPACESUM);CHKERRQ(ierr); 636 ierr = PetscSpaceSumSetNumSubspaces(*sumSpace,numSubspaces);CHKERRQ(ierr); 637 ierr = PetscSpaceSumSetConcatenate(*sumSpace,concatenate);CHKERRQ(ierr); 638 for (i=0; i<numSubspaces; ++i) { 639 PetscInt sNc; 640 641 ierr = PetscSpaceSumSetSubspace(*sumSpace,i,subspaces[i]);CHKERRQ(ierr); 642 ierr = PetscSpaceGetNumComponents(subspaces[i],&sNc);CHKERRQ(ierr); 643 if (concatenate) Nc += sNc; 644 else Nc = sNc; 645 } 646 ierr = PetscSpaceGetNumVariables(subspaces[0],&Nv);CHKERRQ(ierr); 647 ierr = PetscSpaceSetNumComponents(*sumSpace,Nc);CHKERRQ(ierr); 648 ierr = PetscSpaceSetNumVariables(*sumSpace,Nv);CHKERRQ(ierr); 649 ierr = PetscSpaceSetUp(*sumSpace);CHKERRQ(ierr); 650 651 PetscFunctionReturn(0); 652 } 653