1 2 /* 3 Code for manipulating distributed regular arrays in parallel. 4 */ 5 6 #include <private/daimpl.h> /*I "petscdmda.h" I*/ 7 8 /* 9 This allows the DMDA vectors to properly tell MATLAB their dimensions 10 */ 11 #if defined(PETSC_HAVE_MATLAB_ENGINE) 12 #include <engine.h> /* MATLAB include file */ 13 #include <mex.h> /* MATLAB include file */ 14 EXTERN_C_BEGIN 15 #undef __FUNCT__ 16 #define __FUNCT__ "VecMatlabEnginePut_DA2d" 17 PetscErrorCode VecMatlabEnginePut_DA2d(PetscObject obj,void *mengine) 18 { 19 PetscErrorCode ierr; 20 PetscInt n,m; 21 Vec vec = (Vec)obj; 22 PetscScalar *array; 23 mxArray *mat; 24 DM da; 25 26 PetscFunctionBegin; 27 ierr = PetscObjectQuery((PetscObject)vec,"DM",(PetscObject*)&da);CHKERRQ(ierr); 28 if (!da) SETERRQ(((PetscObject)vec)->comm,PETSC_ERR_ARG_WRONGSTATE,"Vector not associated with a DMDA"); 29 ierr = DMDAGetGhostCorners(da,0,0,0,&m,&n,0);CHKERRQ(ierr); 30 31 ierr = VecGetArray(vec,&array);CHKERRQ(ierr); 32 #if !defined(PETSC_USE_COMPLEX) 33 mat = mxCreateDoubleMatrix(m,n,mxREAL); 34 #else 35 mat = mxCreateDoubleMatrix(m,n,mxCOMPLEX); 36 #endif 37 ierr = PetscMemcpy(mxGetPr(mat),array,n*m*sizeof(PetscScalar));CHKERRQ(ierr); 38 ierr = PetscObjectName(obj);CHKERRQ(ierr); 39 engPutVariable((Engine *)mengine,obj->name,mat); 40 41 ierr = VecRestoreArray(vec,&array);CHKERRQ(ierr); 42 PetscFunctionReturn(0); 43 } 44 EXTERN_C_END 45 #endif 46 47 48 #undef __FUNCT__ 49 #define __FUNCT__ "DMCreateLocalVector_DA" 50 PetscErrorCode DMCreateLocalVector_DA(DM da,Vec* g) 51 { 52 PetscErrorCode ierr; 53 DM_DA *dd = (DM_DA*)da->data; 54 55 PetscFunctionBegin; 56 PetscValidHeaderSpecific(da,DM_CLASSID,1); 57 PetscValidPointer(g,2); 58 ierr = VecCreate(PETSC_COMM_SELF,g);CHKERRQ(ierr); 59 ierr = VecSetSizes(*g,dd->nlocal,PETSC_DETERMINE);CHKERRQ(ierr); 60 ierr = VecSetType(*g,da->vectype);CHKERRQ(ierr); 61 ierr = VecSetBlockSize(*g,dd->w);CHKERRQ(ierr); 62 ierr = PetscObjectCompose((PetscObject)*g,"DM",(PetscObject)da);CHKERRQ(ierr); 63 #if defined(PETSC_HAVE_MATLAB_ENGINE) 64 if (dd->w == 1 && dd->dim == 2) { 65 ierr = PetscObjectComposeFunctionDynamic((PetscObject)*g,"PetscMatlabEnginePut_C","VecMatlabEnginePut_DA2d",VecMatlabEnginePut_DA2d);CHKERRQ(ierr); 66 } 67 #endif 68 PetscFunctionReturn(0); 69 } 70 71 #undef __FUNCT__ 72 #define __FUNCT__ "DMGetLocalVector" 73 /*@ 74 DMGetLocalVector - Gets a Seq PETSc vector that 75 may be used with the DMXXX routines. This vector has spaces for the ghost values. 76 77 Not Collective 78 79 Input Parameter: 80 . dm - the distributed array 81 82 Output Parameter: 83 . g - the local vector 84 85 Level: beginner 86 87 Note: 88 The vector values are NOT initialized and may have garbage in them, so you may need 89 to zero them. 90 91 The output parameter, g, is a regular PETSc vector that should be returned with 92 DMRestoreLocalVector() DO NOT call VecDestroy() on it. 93 94 VecStride*() operations can be useful when using DM with dof > 1 95 96 .keywords: distributed array, create, local, vector 97 98 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(), 99 DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(), 100 DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector(), 101 VecStrideMax(), VecStrideMin(), VecStrideNorm() 102 @*/ 103 PetscErrorCode DMGetLocalVector(DM dm,Vec* g) 104 { 105 PetscErrorCode ierr,i; 106 107 PetscFunctionBegin; 108 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 109 PetscValidPointer(g,2); 110 for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 111 if (dm->localin[i]) { 112 *g = dm->localin[i]; 113 dm->localin[i] = PETSC_NULL; 114 goto alldone; 115 } 116 } 117 ierr = DMCreateLocalVector(dm,g);CHKERRQ(ierr); 118 119 alldone: 120 for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 121 if (!dm->localout[i]) { 122 dm->localout[i] = *g; 123 break; 124 } 125 } 126 PetscFunctionReturn(0); 127 } 128 129 #undef __FUNCT__ 130 #define __FUNCT__ "DMRestoreLocalVector" 131 /*@ 132 DMRestoreLocalVector - Returns a Seq PETSc vector that 133 obtained from DMGetLocalVector(). Do not use with vector obtained via 134 DMCreateLocalVector(). 135 136 Not Collective 137 138 Input Parameter: 139 + dm - the distributed array 140 - g - the local vector 141 142 Level: beginner 143 144 .keywords: distributed array, create, local, vector 145 146 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(), 147 DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(), 148 DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMGetLocalVector() 149 @*/ 150 PetscErrorCode DMRestoreLocalVector(DM dm,Vec* g) 151 { 152 PetscErrorCode ierr; 153 PetscInt i,j; 154 155 PetscFunctionBegin; 156 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 157 PetscValidPointer(g,2); 158 for (j=0; j<DM_MAX_WORK_VECTORS; j++) { 159 if (*g == dm->localout[j]) { 160 dm->localout[j] = PETSC_NULL; 161 for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 162 if (!dm->localin[i]) { 163 dm->localin[i] = *g; 164 goto alldone; 165 } 166 } 167 } 168 } 169 ierr = VecDestroy(g);CHKERRQ(ierr); 170 alldone: 171 PetscFunctionReturn(0); 172 } 173 174 #undef __FUNCT__ 175 #define __FUNCT__ "DMGetGlobalVector" 176 /*@ 177 DMGetGlobalVector - Gets a MPI PETSc vector that 178 may be used with the DMXXX routines. 179 180 Collective on DM 181 182 Input Parameter: 183 . dm - the distributed array 184 185 Output Parameter: 186 . g - the global vector 187 188 Level: beginner 189 190 Note: 191 The vector values are NOT initialized and may have garbage in them, so you may need 192 to zero them. 193 194 The output parameter, g, is a regular PETSc vector that should be returned with 195 DMRestoreGlobalVector() DO NOT call VecDestroy() on it. 196 197 VecStride*() operations can be useful when using DM with dof > 1 198 199 .keywords: distributed array, create, Global, vector 200 201 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(), 202 DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(), 203 DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector() 204 VecStrideMax(), VecStrideMin(), VecStrideNorm() 205 206 @*/ 207 PetscErrorCode DMGetGlobalVector(DM dm,Vec* g) 208 { 209 PetscErrorCode ierr; 210 PetscInt i; 211 212 PetscFunctionBegin; 213 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 214 PetscValidPointer(g,2); 215 for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 216 if (dm->globalin[i]) { 217 *g = dm->globalin[i]; 218 dm->globalin[i] = PETSC_NULL; 219 goto alldone; 220 } 221 } 222 ierr = DMCreateGlobalVector(dm,g);CHKERRQ(ierr); 223 224 alldone: 225 for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 226 if (!dm->globalout[i]) { 227 dm->globalout[i] = *g; 228 break; 229 } 230 } 231 PetscFunctionReturn(0); 232 } 233 234 #undef __FUNCT__ 235 #define __FUNCT__ "DMClearGlobalVectors" 236 /*@ 237 DMClearGlobalVectors - Destroys all the global vectors that have been stashed in this DM 238 239 Collective on DM 240 241 Input Parameter: 242 . dm - the distributed array 243 244 Level: developer 245 246 .keywords: distributed array, create, Global, vector 247 248 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(), 249 DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(), 250 DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector() 251 VecStrideMax(), VecStrideMin(), VecStrideNorm() 252 253 @*/ 254 PetscErrorCode DMClearGlobalVectors(DM dm) 255 { 256 PetscErrorCode ierr; 257 PetscInt i; 258 259 PetscFunctionBegin; 260 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 261 for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 262 if (dm->globalout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Clearing DM of global vectors that has a global vector obtained with DMGetGlobalVector()"); 263 ierr = VecDestroy(&dm->globalin[i]);CHKERRQ(ierr); 264 } 265 PetscFunctionReturn(0); 266 } 267 268 #undef __FUNCT__ 269 #define __FUNCT__ "DMRestoreGlobalVector" 270 /*@ 271 DMRestoreGlobalVector - Returns a Seq PETSc vector that 272 obtained from DMGetGlobalVector(). Do not use with vector obtained via 273 DMCreateGlobalVector(). 274 275 Not Collective 276 277 Input Parameter: 278 + dm - the distributed array 279 - g - the global vector 280 281 Level: beginner 282 283 .keywords: distributed array, create, global, vector 284 285 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(), 286 DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(), 287 DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector() 288 @*/ 289 PetscErrorCode DMRestoreGlobalVector(DM dm,Vec* g) 290 { 291 PetscErrorCode ierr; 292 PetscInt i,j; 293 294 PetscFunctionBegin; 295 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 296 PetscValidPointer(g,2); 297 for (j=0; j<DM_MAX_WORK_VECTORS; j++) { 298 if (*g == dm->globalout[j]) { 299 dm->globalout[j] = PETSC_NULL; 300 for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 301 if (!dm->globalin[i]) { 302 dm->globalin[i] = *g; 303 goto alldone; 304 } 305 } 306 } 307 } 308 ierr = VecDestroy(g);CHKERRQ(ierr); 309 alldone: 310 PetscFunctionReturn(0); 311 } 312 313 /* ------------------------------------------------------------------- */ 314 #if defined(PETSC_HAVE_ADIC) 315 316 EXTERN_C_BEGIN 317 #include <adic/ad_utils.h> 318 EXTERN_C_END 319 320 #undef __FUNCT__ 321 #define __FUNCT__ "DMDAGetAdicArray" 322 /*@C 323 DMDAGetAdicArray - Gets an array of derivative types for a DMDA 324 325 Input Parameter: 326 + da - information about my local patch 327 - ghosted - do you want arrays for the ghosted or nonghosted patch 328 329 Output Parameters: 330 + vptr - array data structured to be passed to ad_FormFunctionLocal() 331 . array_start - actual start of 1d array of all values that adiC can access directly (may be null) 332 - tdof - total number of degrees of freedom represented in array_start (may be null) 333 334 Notes: 335 The vector values are NOT initialized and may have garbage in them, so you may need 336 to zero them. 337 338 Returns the same type of object as the DMDAVecGetArray() except its elements are 339 derivative types instead of PetscScalars 340 341 Level: advanced 342 343 .seealso: DMDARestoreAdicArray() 344 345 @*/ 346 PetscErrorCode DMDAGetAdicArray(DM da,PetscBool ghosted,void *vptr,void *array_start,PetscInt *tdof) 347 { 348 PetscErrorCode ierr; 349 PetscInt j,i,deriv_type_size,xs,ys,xm,ym,zs,zm,itdof; 350 char *iarray_start; 351 void **iptr = (void**)vptr; 352 DM_DA *dd = (DM_DA*)da->data; 353 354 PetscFunctionBegin; 355 PetscValidHeaderSpecific(da,DM_CLASSID,1); 356 if (ghosted) { 357 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 358 if (dd->adarrayghostedin[i]) { 359 *iptr = dd->adarrayghostedin[i]; 360 iarray_start = (char*)dd->adstartghostedin[i]; 361 itdof = dd->ghostedtdof; 362 dd->adarrayghostedin[i] = PETSC_NULL; 363 dd->adstartghostedin[i] = PETSC_NULL; 364 365 goto done; 366 } 367 } 368 xs = dd->Xs; 369 ys = dd->Ys; 370 zs = dd->Zs; 371 xm = dd->Xe-dd->Xs; 372 ym = dd->Ye-dd->Ys; 373 zm = dd->Ze-dd->Zs; 374 } else { 375 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 376 if (dd->adarrayin[i]) { 377 *iptr = dd->adarrayin[i]; 378 iarray_start = (char*)dd->adstartin[i]; 379 itdof = dd->tdof; 380 dd->adarrayin[i] = PETSC_NULL; 381 dd->adstartin[i] = PETSC_NULL; 382 383 goto done; 384 } 385 } 386 xs = dd->xs; 387 ys = dd->ys; 388 zs = dd->zs; 389 xm = dd->xe-dd->xs; 390 ym = dd->ye-dd->ys; 391 zm = dd->ze-dd->zs; 392 } 393 deriv_type_size = PetscADGetDerivTypeSize(); 394 395 switch (dd->dim) { 396 case 1: { 397 void *ptr; 398 itdof = xm; 399 400 ierr = PetscMalloc(xm*deriv_type_size,&iarray_start);CHKERRQ(ierr); 401 402 ptr = (void*)(iarray_start - xs*deriv_type_size); 403 *iptr = (void*)ptr; 404 break;} 405 case 2: { 406 void **ptr; 407 itdof = xm*ym; 408 409 ierr = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*deriv_type_size,&iarray_start);CHKERRQ(ierr); 410 411 ptr = (void**)(iarray_start + xm*ym*deriv_type_size - ys*sizeof(void*)); 412 for(j=ys;j<ys+ym;j++) { 413 ptr[j] = iarray_start + deriv_type_size*(xm*(j-ys) - xs); 414 } 415 *iptr = (void*)ptr; 416 break;} 417 case 3: { 418 void ***ptr,**bptr; 419 itdof = xm*ym*zm; 420 421 ierr = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*deriv_type_size,&iarray_start);CHKERRQ(ierr); 422 423 ptr = (void***)(iarray_start + xm*ym*zm*deriv_type_size - zs*sizeof(void*)); 424 bptr = (void**)(iarray_start + xm*ym*zm*deriv_type_size + zm*sizeof(void**)); 425 426 for(i=zs;i<zs+zm;i++) { 427 ptr[i] = bptr + ((i-zs)*ym - ys); 428 } 429 for (i=zs; i<zs+zm; i++) { 430 for (j=ys; j<ys+ym; j++) { 431 ptr[i][j] = iarray_start + deriv_type_size*(xm*ym*(i-zs) + xm*(j-ys) - xs); 432 } 433 } 434 435 *iptr = (void*)ptr; 436 break;} 437 default: 438 SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim); 439 } 440 441 done: 442 /* add arrays to the checked out list */ 443 if (ghosted) { 444 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 445 if (!dd->adarrayghostedout[i]) { 446 dd->adarrayghostedout[i] = *iptr ; 447 dd->adstartghostedout[i] = iarray_start; 448 dd->ghostedtdof = itdof; 449 break; 450 } 451 } 452 } else { 453 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 454 if (!dd->adarrayout[i]) { 455 dd->adarrayout[i] = *iptr ; 456 dd->adstartout[i] = iarray_start; 457 dd->tdof = itdof; 458 break; 459 } 460 } 461 } 462 if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Too many DMDA ADIC arrays obtained"); 463 if (tdof) *tdof = itdof; 464 if (array_start) *(void**)array_start = iarray_start; 465 PetscFunctionReturn(0); 466 } 467 468 #undef __FUNCT__ 469 #define __FUNCT__ "DMDARestoreAdicArray" 470 /*@C 471 DMDARestoreAdicArray - Restores an array of derivative types for a DMDA 472 473 Input Parameter: 474 + da - information about my local patch 475 - ghosted - do you want arrays for the ghosted or nonghosted patch 476 477 Output Parameters: 478 + ptr - array data structured to be passed to ad_FormFunctionLocal() 479 . array_start - actual start of 1d array of all values that adiC can access directly 480 - tdof - total number of degrees of freedom represented in array_start 481 482 Level: advanced 483 484 .seealso: DMDAGetAdicArray() 485 486 @*/ 487 PetscErrorCode DMDARestoreAdicArray(DM da,PetscBool ghosted,void *ptr,void *array_start,PetscInt *tdof) 488 { 489 PetscInt i; 490 void **iptr = (void**)ptr,iarray_start = 0; 491 492 PetscFunctionBegin; 493 PetscValidHeaderSpecific(da,DM_CLASSID,1); 494 if (ghosted) { 495 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 496 if (dd->adarrayghostedout[i] == *iptr) { 497 iarray_start = dd->adstartghostedout[i]; 498 dd->adarrayghostedout[i] = PETSC_NULL; 499 dd->adstartghostedout[i] = PETSC_NULL; 500 break; 501 } 502 } 503 if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list"); 504 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 505 if (!dd->adarrayghostedin[i]){ 506 dd->adarrayghostedin[i] = *iptr; 507 dd->adstartghostedin[i] = iarray_start; 508 break; 509 } 510 } 511 } else { 512 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 513 if (dd->adarrayout[i] == *iptr) { 514 iarray_start = dd->adstartout[i]; 515 dd->adarrayout[i] = PETSC_NULL; 516 dd->adstartout[i] = PETSC_NULL; 517 break; 518 } 519 } 520 if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list"); 521 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 522 if (!dd->adarrayin[i]){ 523 dd->adarrayin[i] = *iptr; 524 dd->adstartin[i] = iarray_start; 525 break; 526 } 527 } 528 } 529 PetscFunctionReturn(0); 530 } 531 532 #undef __FUNCT__ 533 #define __FUNCT__ "ad_DAGetArray" 534 PetscErrorCode ad_DAGetArray(DM da,PetscBool ghosted,void *iptr) 535 { 536 PetscErrorCode ierr; 537 PetscFunctionBegin; 538 ierr = DMDAGetAdicArray(da,ghosted,iptr,0,0);CHKERRQ(ierr); 539 PetscFunctionReturn(0); 540 } 541 542 #undef __FUNCT__ 543 #define __FUNCT__ "ad_DARestoreArray" 544 PetscErrorCode ad_DARestoreArray(DM da,PetscBool ghosted,void *iptr) 545 { 546 PetscErrorCode ierr; 547 PetscFunctionBegin; 548 ierr = DMDARestoreAdicArray(da,ghosted,iptr,0,0);CHKERRQ(ierr); 549 PetscFunctionReturn(0); 550 } 551 552 #endif 553 554 #undef __FUNCT__ 555 #define __FUNCT__ "DMDAGetArray" 556 /*@C 557 DMDAGetArray - Gets a work array for a DMDA 558 559 Input Parameter: 560 + da - information about my local patch 561 - ghosted - do you want arrays for the ghosted or nonghosted patch 562 563 Output Parameters: 564 . vptr - array data structured 565 566 Note: The vector values are NOT initialized and may have garbage in them, so you may need 567 to zero them. 568 569 Level: advanced 570 571 .seealso: DMDARestoreArray(), DMDAGetAdicArray() 572 573 @*/ 574 PetscErrorCode DMDAGetArray(DM da,PetscBool ghosted,void *vptr) 575 { 576 PetscErrorCode ierr; 577 PetscInt j,i,xs,ys,xm,ym,zs,zm; 578 char *iarray_start; 579 void **iptr = (void**)vptr; 580 DM_DA *dd = (DM_DA*)da->data; 581 582 PetscFunctionBegin; 583 PetscValidHeaderSpecific(da,DM_CLASSID,1); 584 if (ghosted) { 585 for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 586 if (dd->arrayghostedin[i]) { 587 *iptr = dd->arrayghostedin[i]; 588 iarray_start = (char*)dd->startghostedin[i]; 589 dd->arrayghostedin[i] = PETSC_NULL; 590 dd->startghostedin[i] = PETSC_NULL; 591 592 goto done; 593 } 594 } 595 xs = dd->Xs; 596 ys = dd->Ys; 597 zs = dd->Zs; 598 xm = dd->Xe-dd->Xs; 599 ym = dd->Ye-dd->Ys; 600 zm = dd->Ze-dd->Zs; 601 } else { 602 for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 603 if (dd->arrayin[i]) { 604 *iptr = dd->arrayin[i]; 605 iarray_start = (char*)dd->startin[i]; 606 dd->arrayin[i] = PETSC_NULL; 607 dd->startin[i] = PETSC_NULL; 608 609 goto done; 610 } 611 } 612 xs = dd->xs; 613 ys = dd->ys; 614 zs = dd->zs; 615 xm = dd->xe-dd->xs; 616 ym = dd->ye-dd->ys; 617 zm = dd->ze-dd->zs; 618 } 619 620 switch (dd->dim) { 621 case 1: { 622 void *ptr; 623 624 ierr = PetscMalloc(xm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 625 626 ptr = (void*)(iarray_start - xs*sizeof(PetscScalar)); 627 *iptr = (void*)ptr; 628 break;} 629 case 2: { 630 void **ptr; 631 632 ierr = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 633 634 ptr = (void**)(iarray_start + xm*ym*sizeof(PetscScalar) - ys*sizeof(void*)); 635 for(j=ys;j<ys+ym;j++) { 636 ptr[j] = iarray_start + sizeof(PetscScalar)*(xm*(j-ys) - xs); 637 } 638 *iptr = (void*)ptr; 639 break;} 640 case 3: { 641 void ***ptr,**bptr; 642 643 ierr = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 644 645 ptr = (void***)(iarray_start + xm*ym*zm*sizeof(PetscScalar) - zs*sizeof(void*)); 646 bptr = (void**)(iarray_start + xm*ym*zm*sizeof(PetscScalar) + zm*sizeof(void**)); 647 for(i=zs;i<zs+zm;i++) { 648 ptr[i] = bptr + ((i-zs)*ym - ys); 649 } 650 for (i=zs; i<zs+zm; i++) { 651 for (j=ys; j<ys+ym; j++) { 652 ptr[i][j] = iarray_start + sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs); 653 } 654 } 655 656 *iptr = (void*)ptr; 657 break;} 658 default: 659 SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim); 660 } 661 662 done: 663 /* add arrays to the checked out list */ 664 if (ghosted) { 665 for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 666 if (!dd->arrayghostedout[i]) { 667 dd->arrayghostedout[i] = *iptr ; 668 dd->startghostedout[i] = iarray_start; 669 break; 670 } 671 } 672 } else { 673 for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 674 if (!dd->arrayout[i]) { 675 dd->arrayout[i] = *iptr ; 676 dd->startout[i] = iarray_start; 677 break; 678 } 679 } 680 } 681 PetscFunctionReturn(0); 682 } 683 684 #undef __FUNCT__ 685 #define __FUNCT__ "DMDARestoreArray" 686 /*@C 687 DMDARestoreArray - Restores an array of derivative types for a DMDA 688 689 Input Parameter: 690 + da - information about my local patch 691 . ghosted - do you want arrays for the ghosted or nonghosted patch 692 - vptr - array data structured to be passed to ad_FormFunctionLocal() 693 694 Level: advanced 695 696 .seealso: DMDAGetArray(), DMDAGetAdicArray() 697 698 @*/ 699 PetscErrorCode DMDARestoreArray(DM da,PetscBool ghosted,void *vptr) 700 { 701 PetscInt i; 702 void **iptr = (void**)vptr,*iarray_start = 0; 703 DM_DA *dd = (DM_DA*)da->data; 704 705 PetscFunctionBegin; 706 PetscValidHeaderSpecific(da,DM_CLASSID,1); 707 if (ghosted) { 708 for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 709 if (dd->arrayghostedout[i] == *iptr) { 710 iarray_start = dd->startghostedout[i]; 711 dd->arrayghostedout[i] = PETSC_NULL; 712 dd->startghostedout[i] = PETSC_NULL; 713 break; 714 } 715 } 716 for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 717 if (!dd->arrayghostedin[i]){ 718 dd->arrayghostedin[i] = *iptr; 719 dd->startghostedin[i] = iarray_start; 720 break; 721 } 722 } 723 } else { 724 for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 725 if (dd->arrayout[i] == *iptr) { 726 iarray_start = dd->startout[i]; 727 dd->arrayout[i] = PETSC_NULL; 728 dd->startout[i] = PETSC_NULL; 729 break; 730 } 731 } 732 for (i=0; i<DMDA_MAX_WORK_ARRAYS; i++) { 733 if (!dd->arrayin[i]){ 734 dd->arrayin[i] = *iptr; 735 dd->startin[i] = iarray_start; 736 break; 737 } 738 } 739 } 740 PetscFunctionReturn(0); 741 } 742 743 #undef __FUNCT__ 744 #define __FUNCT__ "DMDAGetAdicMFArray" 745 /*@C 746 DMDAGetAdicMFArray - Gets an array of derivative types for a DMDA for matrix-free ADIC. 747 748 Input Parameter: 749 + da - information about my local patch 750 - ghosted - do you want arrays for the ghosted or nonghosted patch? 751 752 Output Parameters: 753 + vptr - array data structured to be passed to ad_FormFunctionLocal() 754 . array_start - actual start of 1d array of all values that adiC can access directly (may be null) 755 - tdof - total number of degrees of freedom represented in array_start (may be null) 756 757 Notes: 758 The vector values are NOT initialized and may have garbage in them, so you may need 759 to zero them. 760 761 This routine returns the same type of object as the DMDAVecGetArray(), except its 762 elements are derivative types instead of PetscScalars. 763 764 Level: advanced 765 766 .seealso: DMDARestoreAdicMFArray(), DMDAGetArray(), DMDAGetAdicArray() 767 768 @*/ 769 PetscErrorCode DMDAGetAdicMFArray(DM da,PetscBool ghosted,void *vptr,void *array_start,PetscInt *tdof) 770 { 771 PetscErrorCode ierr; 772 PetscInt j,i,xs,ys,xm,ym,zs,zm,itdof = 0; 773 char *iarray_start; 774 void **iptr = (void**)vptr; 775 DM_DA *dd = (DM_DA*)da->data; 776 777 PetscFunctionBegin; 778 PetscValidHeaderSpecific(da,DM_CLASSID,1); 779 if (ghosted) { 780 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 781 if (dd->admfarrayghostedin[i]) { 782 *iptr = dd->admfarrayghostedin[i]; 783 iarray_start = (char*)dd->admfstartghostedin[i]; 784 itdof = dd->ghostedtdof; 785 dd->admfarrayghostedin[i] = PETSC_NULL; 786 dd->admfstartghostedin[i] = PETSC_NULL; 787 788 goto done; 789 } 790 } 791 xs = dd->Xs; 792 ys = dd->Ys; 793 zs = dd->Zs; 794 xm = dd->Xe-dd->Xs; 795 ym = dd->Ye-dd->Ys; 796 zm = dd->Ze-dd->Zs; 797 } else { 798 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 799 if (dd->admfarrayin[i]) { 800 *iptr = dd->admfarrayin[i]; 801 iarray_start = (char*)dd->admfstartin[i]; 802 itdof = dd->tdof; 803 dd->admfarrayin[i] = PETSC_NULL; 804 dd->admfstartin[i] = PETSC_NULL; 805 806 goto done; 807 } 808 } 809 xs = dd->xs; 810 ys = dd->ys; 811 zs = dd->zs; 812 xm = dd->xe-dd->xs; 813 ym = dd->ye-dd->ys; 814 zm = dd->ze-dd->zs; 815 } 816 817 switch (dd->dim) { 818 case 1: { 819 void *ptr; 820 itdof = xm; 821 822 ierr = PetscMalloc(xm*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 823 824 ptr = (void*)(iarray_start - xs*2*sizeof(PetscScalar)); 825 *iptr = (void*)ptr; 826 break;} 827 case 2: { 828 void **ptr; 829 itdof = xm*ym; 830 831 ierr = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 832 833 ptr = (void**)(iarray_start + xm*ym*2*sizeof(PetscScalar) - ys*sizeof(void*)); 834 for(j=ys;j<ys+ym;j++) { 835 ptr[j] = iarray_start + 2*sizeof(PetscScalar)*(xm*(j-ys) - xs); 836 } 837 *iptr = (void*)ptr; 838 break;} 839 case 3: { 840 void ***ptr,**bptr; 841 itdof = xm*ym*zm; 842 843 ierr = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*2*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 844 845 ptr = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*)); 846 bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**)); 847 for(i=zs;i<zs+zm;i++) { 848 ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*); 849 } 850 for (i=zs; i<zs+zm; i++) { 851 for (j=ys; j<ys+ym; j++) { 852 ptr[i][j] = iarray_start + 2*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs); 853 } 854 } 855 856 *iptr = (void*)ptr; 857 break;} 858 default: 859 SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim); 860 } 861 862 done: 863 /* add arrays to the checked out list */ 864 if (ghosted) { 865 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 866 if (!dd->admfarrayghostedout[i]) { 867 dd->admfarrayghostedout[i] = *iptr ; 868 dd->admfstartghostedout[i] = iarray_start; 869 dd->ghostedtdof = itdof; 870 break; 871 } 872 } 873 } else { 874 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 875 if (!dd->admfarrayout[i]) { 876 dd->admfarrayout[i] = *iptr ; 877 dd->admfstartout[i] = iarray_start; 878 dd->tdof = itdof; 879 break; 880 } 881 } 882 } 883 if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained"); 884 if (tdof) *tdof = itdof; 885 if (array_start) *(void**)array_start = iarray_start; 886 PetscFunctionReturn(0); 887 } 888 889 #undef __FUNCT__ 890 #define __FUNCT__ "DMDAGetAdicMFArray4" 891 PetscErrorCode DMDAGetAdicMFArray4(DM da,PetscBool ghosted,void *vptr,void *array_start,PetscInt *tdof) 892 { 893 PetscErrorCode ierr; 894 PetscInt j,i,xs,ys,xm,ym,zs,zm,itdof = 0; 895 char *iarray_start; 896 void **iptr = (void**)vptr; 897 DM_DA *dd = (DM_DA*)da->data; 898 899 PetscFunctionBegin; 900 PetscValidHeaderSpecific(da,DM_CLASSID,1); 901 if (ghosted) { 902 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 903 if (dd->admfarrayghostedin[i]) { 904 *iptr = dd->admfarrayghostedin[i]; 905 iarray_start = (char*)dd->admfstartghostedin[i]; 906 itdof = dd->ghostedtdof; 907 dd->admfarrayghostedin[i] = PETSC_NULL; 908 dd->admfstartghostedin[i] = PETSC_NULL; 909 910 goto done; 911 } 912 } 913 xs = dd->Xs; 914 ys = dd->Ys; 915 zs = dd->Zs; 916 xm = dd->Xe-dd->Xs; 917 ym = dd->Ye-dd->Ys; 918 zm = dd->Ze-dd->Zs; 919 } else { 920 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 921 if (dd->admfarrayin[i]) { 922 *iptr = dd->admfarrayin[i]; 923 iarray_start = (char*)dd->admfstartin[i]; 924 itdof = dd->tdof; 925 dd->admfarrayin[i] = PETSC_NULL; 926 dd->admfstartin[i] = PETSC_NULL; 927 928 goto done; 929 } 930 } 931 xs = dd->xs; 932 ys = dd->ys; 933 zs = dd->zs; 934 xm = dd->xe-dd->xs; 935 ym = dd->ye-dd->ys; 936 zm = dd->ze-dd->zs; 937 } 938 939 switch (dd->dim) { 940 case 2: { 941 void **ptr; 942 itdof = xm*ym; 943 944 ierr = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*5*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 945 946 ptr = (void**)(iarray_start + xm*ym*5*sizeof(PetscScalar) - ys*sizeof(void*)); 947 for(j=ys;j<ys+ym;j++) { 948 ptr[j] = iarray_start + 5*sizeof(PetscScalar)*(xm*(j-ys) - xs); 949 } 950 *iptr = (void*)ptr; 951 break;} 952 default: 953 SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim); 954 } 955 956 done: 957 /* add arrays to the checked out list */ 958 if (ghosted) { 959 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 960 if (!dd->admfarrayghostedout[i]) { 961 dd->admfarrayghostedout[i] = *iptr ; 962 dd->admfstartghostedout[i] = iarray_start; 963 dd->ghostedtdof = itdof; 964 break; 965 } 966 } 967 } else { 968 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 969 if (!dd->admfarrayout[i]) { 970 dd->admfarrayout[i] = *iptr ; 971 dd->admfstartout[i] = iarray_start; 972 dd->tdof = itdof; 973 break; 974 } 975 } 976 } 977 if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained"); 978 if (tdof) *tdof = itdof; 979 if (array_start) *(void**)array_start = iarray_start; 980 PetscFunctionReturn(0); 981 } 982 983 #undef __FUNCT__ 984 #define __FUNCT__ "DMDAGetAdicMFArray9" 985 PetscErrorCode DMDAGetAdicMFArray9(DM da,PetscBool ghosted,void *vptr,void *array_start,PetscInt *tdof) 986 { 987 PetscErrorCode ierr; 988 PetscInt j,i,xs,ys,xm,ym,zs,zm,itdof = 0; 989 char *iarray_start; 990 void **iptr = (void**)vptr; 991 DM_DA *dd = (DM_DA*)da->data; 992 993 PetscFunctionBegin; 994 PetscValidHeaderSpecific(da,DM_CLASSID,1); 995 if (ghosted) { 996 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 997 if (dd->admfarrayghostedin[i]) { 998 *iptr = dd->admfarrayghostedin[i]; 999 iarray_start = (char*)dd->admfstartghostedin[i]; 1000 itdof = dd->ghostedtdof; 1001 dd->admfarrayghostedin[i] = PETSC_NULL; 1002 dd->admfstartghostedin[i] = PETSC_NULL; 1003 1004 goto done; 1005 } 1006 } 1007 xs = dd->Xs; 1008 ys = dd->Ys; 1009 zs = dd->Zs; 1010 xm = dd->Xe-dd->Xs; 1011 ym = dd->Ye-dd->Ys; 1012 zm = dd->Ze-dd->Zs; 1013 } else { 1014 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 1015 if (dd->admfarrayin[i]) { 1016 *iptr = dd->admfarrayin[i]; 1017 iarray_start = (char*)dd->admfstartin[i]; 1018 itdof = dd->tdof; 1019 dd->admfarrayin[i] = PETSC_NULL; 1020 dd->admfstartin[i] = PETSC_NULL; 1021 1022 goto done; 1023 } 1024 } 1025 xs = dd->xs; 1026 ys = dd->ys; 1027 zs = dd->zs; 1028 xm = dd->xe-dd->xs; 1029 ym = dd->ye-dd->ys; 1030 zm = dd->ze-dd->zs; 1031 } 1032 1033 switch (dd->dim) { 1034 case 2: { 1035 void **ptr; 1036 itdof = xm*ym; 1037 1038 ierr = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*10*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 1039 1040 ptr = (void**)(iarray_start + xm*ym*10*sizeof(PetscScalar) - ys*sizeof(void*)); 1041 for(j=ys;j<ys+ym;j++) { 1042 ptr[j] = iarray_start + 10*sizeof(PetscScalar)*(xm*(j-ys) - xs); 1043 } 1044 *iptr = (void*)ptr; 1045 break;} 1046 default: 1047 SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim); 1048 } 1049 1050 done: 1051 /* add arrays to the checked out list */ 1052 if (ghosted) { 1053 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 1054 if (!dd->admfarrayghostedout[i]) { 1055 dd->admfarrayghostedout[i] = *iptr ; 1056 dd->admfstartghostedout[i] = iarray_start; 1057 dd->ghostedtdof = itdof; 1058 break; 1059 } 1060 } 1061 } else { 1062 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 1063 if (!dd->admfarrayout[i]) { 1064 dd->admfarrayout[i] = *iptr ; 1065 dd->admfstartout[i] = iarray_start; 1066 dd->tdof = itdof; 1067 break; 1068 } 1069 } 1070 } 1071 if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained"); 1072 if (tdof) *tdof = itdof; 1073 if (array_start) *(void**)array_start = iarray_start; 1074 PetscFunctionReturn(0); 1075 } 1076 1077 #undef __FUNCT__ 1078 #define __FUNCT__ "DMDAGetAdicMFArrayb" 1079 /*@C 1080 DMDAGetAdicMFArrayb - Gets an array of derivative types for a DMDA for matrix-free ADIC. 1081 1082 Input Parameter: 1083 + da - information about my local patch 1084 - ghosted - do you want arrays for the ghosted or nonghosted patch? 1085 1086 Output Parameters: 1087 + vptr - array data structured to be passed to ad_FormFunctionLocal() 1088 . array_start - actual start of 1d array of all values that adiC can access directly (may be null) 1089 - tdof - total number of degrees of freedom represented in array_start (may be null) 1090 1091 Notes: 1092 The vector values are NOT initialized and may have garbage in them, so you may need 1093 to zero them. 1094 1095 This routine returns the same type of object as the DMDAVecGetArray(), except its 1096 elements are derivative types instead of PetscScalars. 1097 1098 Level: advanced 1099 1100 .seealso: DMDARestoreAdicMFArray(), DMDAGetArray(), DMDAGetAdicArray() 1101 1102 @*/ 1103 PetscErrorCode DMDAGetAdicMFArrayb(DM da,PetscBool ghosted,void *vptr,void *array_start,PetscInt *tdof) 1104 { 1105 PetscErrorCode ierr; 1106 PetscInt j,i,xs,ys,xm,ym,zs,zm,itdof = 0; 1107 char *iarray_start; 1108 void **iptr = (void**)vptr; 1109 DM_DA *dd = (DM_DA*)da->data; 1110 PetscInt bs = dd->w,bs1 = bs+1; 1111 1112 PetscFunctionBegin; 1113 PetscValidHeaderSpecific(da,DM_CLASSID,1); 1114 if (ghosted) { 1115 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 1116 if (dd->admfarrayghostedin[i]) { 1117 *iptr = dd->admfarrayghostedin[i]; 1118 iarray_start = (char*)dd->admfstartghostedin[i]; 1119 itdof = dd->ghostedtdof; 1120 dd->admfarrayghostedin[i] = PETSC_NULL; 1121 dd->admfstartghostedin[i] = PETSC_NULL; 1122 1123 goto done; 1124 } 1125 } 1126 xs = dd->Xs; 1127 ys = dd->Ys; 1128 zs = dd->Zs; 1129 xm = dd->Xe-dd->Xs; 1130 ym = dd->Ye-dd->Ys; 1131 zm = dd->Ze-dd->Zs; 1132 } else { 1133 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 1134 if (dd->admfarrayin[i]) { 1135 *iptr = dd->admfarrayin[i]; 1136 iarray_start = (char*)dd->admfstartin[i]; 1137 itdof = dd->tdof; 1138 dd->admfarrayin[i] = PETSC_NULL; 1139 dd->admfstartin[i] = PETSC_NULL; 1140 1141 goto done; 1142 } 1143 } 1144 xs = dd->xs; 1145 ys = dd->ys; 1146 zs = dd->zs; 1147 xm = dd->xe-dd->xs; 1148 ym = dd->ye-dd->ys; 1149 zm = dd->ze-dd->zs; 1150 } 1151 1152 switch (dd->dim) { 1153 case 1: { 1154 void *ptr; 1155 itdof = xm; 1156 1157 ierr = PetscMalloc(xm*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 1158 1159 ptr = (void*)(iarray_start - xs*bs1*sizeof(PetscScalar)); 1160 *iptr = (void*)ptr; 1161 break;} 1162 case 2: { 1163 void **ptr; 1164 itdof = xm*ym; 1165 1166 ierr = PetscMalloc((ym+1)*sizeof(void*)+xm*ym*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 1167 1168 ptr = (void**)(iarray_start + xm*ym*bs1*sizeof(PetscScalar) - ys*sizeof(void*)); 1169 for(j=ys;j<ys+ym;j++) { 1170 ptr[j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*(j-ys) - xs); 1171 } 1172 *iptr = (void*)ptr; 1173 break;} 1174 case 3: { 1175 void ***ptr,**bptr; 1176 itdof = xm*ym*zm; 1177 1178 ierr = PetscMalloc((zm+1)*sizeof(void **)+(ym*zm+1)*sizeof(void*)+xm*ym*zm*bs1*sizeof(PetscScalar),&iarray_start);CHKERRQ(ierr); 1179 1180 ptr = (void***)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) - zs*sizeof(void*)); 1181 bptr = (void**)(iarray_start + xm*ym*zm*2*sizeof(PetscScalar) + zm*sizeof(void**)); 1182 for(i=zs;i<zs+zm;i++) { 1183 ptr[i] = bptr + ((i-zs)*ym* - ys)*sizeof(void*); 1184 } 1185 for (i=zs; i<zs+zm; i++) { 1186 for (j=ys; j<ys+ym; j++) { 1187 ptr[i][j] = iarray_start + bs1*sizeof(PetscScalar)*(xm*ym*(i-zs) + xm*(j-ys) - xs); 1188 } 1189 } 1190 1191 *iptr = (void*)ptr; 1192 break;} 1193 default: 1194 SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Dimension %D not supported",dd->dim); 1195 } 1196 1197 done: 1198 /* add arrays to the checked out list */ 1199 if (ghosted) { 1200 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 1201 if (!dd->admfarrayghostedout[i]) { 1202 dd->admfarrayghostedout[i] = *iptr ; 1203 dd->admfstartghostedout[i] = iarray_start; 1204 dd->ghostedtdof = itdof; 1205 break; 1206 } 1207 } 1208 } else { 1209 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 1210 if (!dd->admfarrayout[i]) { 1211 dd->admfarrayout[i] = *iptr ; 1212 dd->admfstartout[i] = iarray_start; 1213 dd->tdof = itdof; 1214 break; 1215 } 1216 } 1217 } 1218 if (i == DMDA_MAX_AD_ARRAYS+1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Too many DMDA ADIC arrays obtained"); 1219 if (tdof) *tdof = itdof; 1220 if (array_start) *(void**)array_start = iarray_start; 1221 PetscFunctionReturn(0); 1222 } 1223 1224 #undef __FUNCT__ 1225 #define __FUNCT__ "DMDARestoreAdicMFArray" 1226 /*@C 1227 DMDARestoreAdicMFArray - Restores an array of derivative types for a DMDA. 1228 1229 Input Parameter: 1230 + da - information about my local patch 1231 - ghosted - do you want arrays for the ghosted or nonghosted patch? 1232 1233 Output Parameters: 1234 + ptr - array data structure to be passed to ad_FormFunctionLocal() 1235 . array_start - actual start of 1d array of all values that adiC can access directly 1236 - tdof - total number of degrees of freedom represented in array_start 1237 1238 Level: advanced 1239 1240 .seealso: DMDAGetAdicArray() 1241 1242 @*/ 1243 PetscErrorCode DMDARestoreAdicMFArray(DM da,PetscBool ghosted,void *vptr,void *array_start,PetscInt *tdof) 1244 { 1245 PetscInt i; 1246 void **iptr = (void**)vptr,*iarray_start = 0; 1247 DM_DA *dd = (DM_DA*)da->data; 1248 1249 PetscFunctionBegin; 1250 PetscValidHeaderSpecific(da,DM_CLASSID,1); 1251 if (ghosted) { 1252 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 1253 if (dd->admfarrayghostedout[i] == *iptr) { 1254 iarray_start = dd->admfstartghostedout[i]; 1255 dd->admfarrayghostedout[i] = PETSC_NULL; 1256 dd->admfstartghostedout[i] = PETSC_NULL; 1257 break; 1258 } 1259 } 1260 if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list"); 1261 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 1262 if (!dd->admfarrayghostedin[i]){ 1263 dd->admfarrayghostedin[i] = *iptr; 1264 dd->admfstartghostedin[i] = iarray_start; 1265 break; 1266 } 1267 } 1268 } else { 1269 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 1270 if (dd->admfarrayout[i] == *iptr) { 1271 iarray_start = dd->admfstartout[i]; 1272 dd->admfarrayout[i] = PETSC_NULL; 1273 dd->admfstartout[i] = PETSC_NULL; 1274 break; 1275 } 1276 } 1277 if (!iarray_start) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Could not find array in checkout list"); 1278 for (i=0; i<DMDA_MAX_AD_ARRAYS; i++) { 1279 if (!dd->admfarrayin[i]){ 1280 dd->admfarrayin[i] = *iptr; 1281 dd->admfstartin[i] = iarray_start; 1282 break; 1283 } 1284 } 1285 } 1286 PetscFunctionReturn(0); 1287 } 1288 1289 #undef __FUNCT__ 1290 #define __FUNCT__ "admf_DAGetArray" 1291 PetscErrorCode admf_DAGetArray(DM da,PetscBool ghosted,void *iptr) 1292 { 1293 PetscErrorCode ierr; 1294 PetscFunctionBegin; 1295 ierr = DMDAGetAdicMFArray(da,ghosted,iptr,0,0);CHKERRQ(ierr); 1296 PetscFunctionReturn(0); 1297 } 1298 1299 #undef __FUNCT__ 1300 #define __FUNCT__ "admf_DARestoreArray" 1301 PetscErrorCode admf_DARestoreArray(DM da,PetscBool ghosted,void *iptr) 1302 { 1303 PetscErrorCode ierr; 1304 PetscFunctionBegin; 1305 ierr = DMDARestoreAdicMFArray(da,ghosted,iptr,0,0);CHKERRQ(ierr); 1306 PetscFunctionReturn(0); 1307 } 1308 1309