Actual source code: matadic.c

  1: #define PETSCMAT_DLL

  3: /*
  4:     ADIC matrix-free matrix implementation
  5: */

 7:  #include private/matimpl.h
 8:  #include petscda.h
 9:  #include petscsnes.h
 11: #include "adic/ad_utils.h"

 14: typedef struct {
 15:   DA         da;
 16:   Vec        localu;         /* point at which Jacobian is evaluated */
 17:   void       *ctx;
 18:   SNES       snes;
 19:   Vec        diagonal;       /* current matrix diagonal */
 20:   PetscTruth diagonalvalid;  /* indicates if diagonal matches current base vector */
 21: } Mat_DAAD;

 25: PetscErrorCode MatAssemblyEnd_DAAD(Mat A,MatAssemblyType atype)
 26: {
 27:   Mat_DAAD *a = (Mat_DAAD*)A->data;
 29:   Vec      u;

 32:   a->diagonalvalid = PETSC_FALSE;
 33:   if (a->snes) {
 34:     SNESGetSolution(a->snes,&u);
 35:     DAGlobalToLocalBegin(a->da,u,INSERT_VALUES,a->localu);
 36:     DAGlobalToLocalEnd(a->da,u,INSERT_VALUES,a->localu);
 37:   }
 38:   return(0);
 39: }

 43: PetscErrorCode MatMult_DAAD(Mat A,Vec xx,Vec yy)
 44: {
 45:   Mat_DAAD *a = (Mat_DAAD*)A->data;
 46:   Vec      localxx;

 50:   DAGetLocalVector(a->da,&localxx);
 51:   DAGlobalToLocalBegin(a->da,xx,INSERT_VALUES,localxx);
 52:   DAGlobalToLocalEnd(a->da,xx,INSERT_VALUES,localxx);
 53:   DAMultiplyByJacobian1WithAD(a->da,a->localu,localxx,yy,a->ctx);
 54:   DARestoreLocalVector(a->da,&localxx);
 55:   return(0);
 56: }

 58: #include "../src/dm/da/daimpl.h"

 62: PetscErrorCode MatGetDiagonal_DAAD(Mat A,Vec dd)
 63: {
 64:   Mat_DAAD      *a = (Mat_DAAD*)A->data;
 66:   int j,nI,gI,gtdof;
 67:   PetscScalar   *avu,*ad_vustart,ad_f[2],*d;
 68:   DALocalInfo   info;
 69:   MatStencil    stencil;
 70:   void*         *ad_vu;


 74:   /* get space for derivative object.  */
 75:   DAGetAdicMFArray(a->da,PETSC_TRUE,(void **)&ad_vu,(void**)&ad_vustart,&gtdof);

 77:   /* copy input vector into derivative object */
 78:   VecGetArray(a->localu,&avu);
 79:   for (j=0; j<gtdof; j++) {
 80:     ad_vustart[2*j]   = avu[j];
 81:     ad_vustart[2*j+1] = 0.0;
 82:   }
 83:   VecRestoreArray(a->localu,&avu);

 85:   PetscADResetIndep();
 86:   PetscADIncrementTotalGradSize(1);
 87:   PetscADSetIndepDone();

 89:   VecGetArray(dd,&d);

 91:   DAGetLocalInfo(a->da,&info);
 92:   nI = 0;
 93:   for (stencil.k = info.zs; stencil.k<info.zs+info.zm; stencil.k++) {
 94:     for (stencil.j = info.ys; stencil.j<info.ys+info.ym; stencil.j++) {
 95:       for (stencil.i = info.xs; stencil.i<info.xs+info.xm; stencil.i++) {
 96:         for (stencil.c = 0; stencil.c<info.dof; stencil.c++) {
 97:           gI   = stencil.c + (stencil.i - info.gxs)*info.dof + (stencil.j - info.gys)*info.dof*info.gxm + (stencil.k - info.gzs)*info.dof*info.gxm*info.gym;
 98:           ad_vustart[1+2*gI] = 1.0;
 99:           (*a->da->adicmf_lfi)(&info,&stencil,ad_vu,ad_f,a->ctx);
100:           d[nI] = ad_f[1];
101:           ad_vustart[1+2*gI] = 0.0;
102:           nI++;
103:         }
104:       }
105:     }
106:   }

108:   VecRestoreArray(dd,&d);
109:   DARestoreAdicMFArray(a->da,PETSC_TRUE,(void **)&ad_vu,(void**)&ad_vustart,&gtdof);
110:   return(0);
111: }


116: PetscErrorCode MatSOR_DAAD(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,int its,int lits,Vec xx)
117: {
118:   Mat_DAAD      *a = (Mat_DAAD*)A->data;
120:   int j,gtdof,nI,gI;
121:   PetscScalar   *avu,*av,*ad_vustart,ad_f[2],*d,*b;
122:   Vec           localxx,dd;
123:   DALocalInfo   info;
124:   MatStencil    stencil;
125:   void*         *ad_vu;

128:   if (omega != 1.0) SETERRQ(PETSC_ERR_ARG_WRONG,"Currently only support omega of 1.0");
129:   if (fshift)       SETERRQ(PETSC_ERR_ARG_WRONG,"Currently do not support fshift");
130:   if (its <= 0 || lits <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D and local its %D both positive",its,lits);

132:   if (!a->diagonal) {
133:     DACreateGlobalVector(a->da,&a->diagonal);
134:   }
135:   if (!a->diagonalvalid) {
136:     MatGetDiagonal(A,a->diagonal);
137:     a->diagonalvalid = PETSC_TRUE;
138:   }
139:   dd   = a->diagonal;


142:   DAGetLocalVector(a->da,&localxx);
143:   if (flag & SOR_ZERO_INITIAL_GUESS) {
144:     VecSet(localxx,0.0);
145:   } else {
146:     DAGlobalToLocalBegin(a->da,xx,INSERT_VALUES,localxx);
147:     DAGlobalToLocalEnd(a->da,xx,INSERT_VALUES,localxx);
148:   }

150:   /* get space for derivative object.  */
151:   DAGetAdicMFArray(a->da,PETSC_TRUE,(void **)&ad_vu,(void**)&ad_vustart,&gtdof);

153:   /* copy input vector into derivative object */
154:   VecGetArray(a->localu,&avu);
155:   VecGetArray(localxx,&av);
156:   for (j=0; j<gtdof; j++) {
157:     ad_vustart[2*j]   = avu[j];
158:     ad_vustart[2*j+1] = av[j];
159:   }
160:   VecRestoreArray(a->localu,&avu);
161:   VecRestoreArray(localxx,&av);

163:   PetscADResetIndep();
164:   PetscADIncrementTotalGradSize(1);
165:   PetscADSetIndepDone();

167:   VecGetArray(dd,&d);
168:   VecGetArray(bb,&b);

170:   DAGetLocalInfo(a->da,&info);
171:   while (its--) {
172:     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
173:       nI = 0;
174:       for (stencil.k = info.zs; stencil.k<info.zs+info.zm; stencil.k++) {
175:         for (stencil.j = info.ys; stencil.j<info.ys+info.ym; stencil.j++) {
176:           for (stencil.i = info.xs; stencil.i<info.xs+info.xm; stencil.i++) {
177:             for (stencil.c = 0; stencil.c<info.dof; stencil.c++) {
178:               (*a->da->adicmf_lfi)(&info,&stencil,ad_vu,ad_f,a->ctx);
179:               gI   = stencil.c + (stencil.i - info.gxs)*info.dof + (stencil.j - info.gys)*info.dof*info.gxm + (stencil.k - info.gzs)*info.dof*info.gxm*info.gym;
180:               ad_vustart[1+2*gI] += (b[nI] - ad_f[1])/d[nI];
181:               nI++;
182:             }
183:           }
184:         }
185:       }
186:     }
187:     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
188:       nI = info.dof*info.xm*info.ym*info.zm - 1;
189:       for (stencil.k = info.zs+info.zm-1; stencil.k>=info.zs; stencil.k--) {
190:         for (stencil.j = info.ys+info.ym-1; stencil.j>=info.ys; stencil.j--) {
191:           for (stencil.i = info.xs+info.xm-1; stencil.i>=info.xs; stencil.i--) {
192:             for (stencil.c = info.dof-1; stencil.c>=0; stencil.c--) {
193:               (*a->da->adicmf_lfi)(&info,&stencil,ad_vu,ad_f,a->ctx);
194:               gI   = stencil.c + (stencil.i - info.gxs)*info.dof + (stencil.j - info.gys)*info.dof*info.gxm + (stencil.k - info.gzs)*info.dof*info.gxm*info.gym;
195:               ad_vustart[1+2*gI] += (b[nI] - ad_f[1])/d[nI];
196:               nI--;
197:             }
198:           }
199:         }
200:       }
201:     }
202:   }

204:   VecRestoreArray(dd,&d);
205:   VecRestoreArray(bb,&b);

207:   VecGetArray(localxx,&av);
208:   for (j=0; j<gtdof; j++) {
209:     av[j] = ad_vustart[2*j+1];
210:   }
211:   VecRestoreArray(localxx,&av);
212:   DALocalToGlobal(a->da,localxx,INSERT_VALUES,xx);

214:   DARestoreLocalVector(a->da,&localxx);
215:   DARestoreAdicMFArray(a->da,PETSC_TRUE,(void **)&ad_vu,(void**)&ad_vustart,&gtdof);
216:   return(0);
217: }



223: PetscErrorCode MatDestroy_DAAD(Mat A)
224: {
225:   Mat_DAAD *a = (Mat_DAAD*)A->data;

229:   DADestroy(a->da);
230:   VecDestroy(a->localu);
231:   if (a->diagonal) {VecDestroy(a->diagonal);}
232:   PetscFree(a);
233:   PetscObjectChangeTypeName((PetscObject)A,0);
234:   PetscObjectComposeFunction((PetscObject)A,"MatMFFDSetBase_C","",PETSC_NULL);
235:   PetscObjectComposeFunction((PetscObject)A,"MatDAADSetDA_C","",PETSC_NULL);
236:   PetscObjectComposeFunction((PetscObject)A,"MatDAADSetSNES_C","",PETSC_NULL);
237:   PetscObjectComposeFunction((PetscObject)A,"MatDAADSetCtx_C","",PETSC_NULL);
238:   return(0);
239: }

241: /* -------------------------------------------------------------------*/
242: static struct _MatOps MatOps_Values = {0,
243:        0,
244:        0,
245:        MatMult_DAAD,
246: /* 4*/ 0,
247:        0,
248:        0,
249:        0,
250:        0,
251:        0,
252: /*10*/ 0,
253:        0,
254:        0,
255:        MatSOR_DAAD,
256:        0,
257: /*15*/ 0,
258:        0,
259:        MatGetDiagonal_DAAD,
260:        0,
261:        0,
262: /*20*/ 0,
263:        MatAssemblyEnd_DAAD,
264:        0,
265:        0,
266: /*24*/ 0,
267:        0,
268:        0,
269:        0,
270:        0,
271: /*29*/ 0,
272:        0,
273:        0,
274:        0,
275:        0,
276: /*34*/ 0,
277:        0,
278:        0,
279:        0,
280:        0,
281: /*39*/ 0,
282:        0,
283:        0,
284:        0,
285:        0,
286: /*44*/ 0,
287:        0,
288:        0,
289:        0,
290:        0,
291: /*49*/ 0,
292:        0,
293:        0,
294:        0,
295:        0,
296: /*54*/ 0,
297:        0,
298:        0,
299:        0,
300:        0,
301: /*59*/ 0,
302:        MatDestroy_DAAD,
303:        0,
304:        0,
305:        0,
306: /*64*/ 0,
307:        0,
308:        0,
309:        0,
310:        0,
311: /*69*/ 0,
312:        0,
313:        0,
314:        0,
315:        0,
316: /*74*/ 0,
317:        0,
318:        0,
319:        0,
320:        0,
321: /*79*/ 0,
322:        0,
323:        0,
324:        0,
325:        0,
326: /*84*/ 0,
327:        0,
328:        0,
329:        0,
330:        0,
331: /*89*/ 0,
332:        0,
333:        0,
334:        0,
335:        0,
336: /*94*/ 0,
337:        0,
338:        0,
339:        0};

341: /* --------------------------------------------------------------------------------*/

346: PetscErrorCode  MatMFFDSetBase_AD(Mat J,Vec U,Vec F)
347: {
349:   Mat_DAAD       *a = (Mat_DAAD*)J->data;

352:   a->diagonalvalid = PETSC_FALSE;
353:   DAGlobalToLocalBegin(a->da,U,INSERT_VALUES,a->localu);
354:   DAGlobalToLocalEnd(a->da,U,INSERT_VALUES,a->localu);
355:   return(0);
356: }

362: PetscErrorCode  MatDAADSetDA_AD(Mat A,DA da)
363: {
364:   Mat_DAAD       *a = (Mat_DAAD*)A->data;
366:   PetscInt       nc,nx,ny,nz,Nx,Ny,Nz;

369:   PetscObjectReference((PetscObject)da);
370:   if (a->da) { DADestroy(a->da); }
371:   a->da = da;
372:   DAGetInfo(da,0,&Nx,&Ny,&Nz,0,0,0,&nc,0,0,0);
373:   DAGetCorners(da,0,0,0,&nx,&ny,&nz);
374:   A->rmap->n  = A->cmap->n = nc*nx*ny*nz;
375:   A->rmap->N  = A->cmap->N = nc*Nx*Ny*Nz;
376:   DACreateLocalVector(da,&a->localu);
377:   return(0);
378: }

384: PetscErrorCode  MatDAADSetSNES_AD(Mat A,SNES snes)
385: {
386:   Mat_DAAD *a = (Mat_DAAD*)A->data;

389:   a->snes = snes;
390:   return(0);
391: }

397: PetscErrorCode  MatDAADSetCtx_AD(Mat A,void *ctx)
398: {
399:   Mat_DAAD *a = (Mat_DAAD*)A->data;

402:   a->ctx = ctx;
403:   return(0);
404: }

407: /*MC
408:   MATDAAD - MATDAAD = "daad" - A matrix type that can do matrix-vector products using a local function that
409:   is differentiated with ADIFOR or ADIC. 

411:   Level: intermediate

413: .seealso: MatCreateDAAD
414: M*/

419: PetscErrorCode  MatCreate_DAAD(Mat B)
420: {
421:   Mat_DAAD       *b;

425:   PetscNewLog(B,Mat_DAAD,&b);
426:   B->data = (void*)b;
427:   PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));
428: 
429:   PetscLayoutSetBlockSize(B->rmap,1);
430:   PetscLayoutSetBlockSize(B->cmap,1);
431:   PetscLayoutSetUp(B->rmap);
432:   PetscLayoutSetUp(B->cmap);

434:   PetscObjectChangeTypeName((PetscObject)B,MATDAAD);
435:   PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMFFDSetBase_C","MatMFFDSetBase_AD",MatMFFDSetBase_AD);
436:   PetscObjectComposeFunctionDynamic((PetscObject)B,"MatDAADSetDA_C","MatDAADSetDA_AD",MatDAADSetDA_AD);
437:   PetscObjectComposeFunctionDynamic((PetscObject)B,"MatDAADSetSNES_C","MatDAADSetSNES_AD",MatDAADSetSNES_AD);
438:   PetscObjectComposeFunctionDynamic((PetscObject)B,"MatDAADSetCtx_C","MatDAADSetCtx_AD",MatDAADSetCtx_AD);
439:   PetscObjectChangeTypeName((PetscObject)B,MATDAAD);
440:   return(0);
441: }


447: /*@C
448:    MatDAADSetDA - Tells the matrix what DA it is using for layout and Jacobian.

450:    Collective on Mat and DA

452:    Input Parameters:
453: +  mat - the matrix
454: -  da - the DA

456:    Level: intermediate

458: .seealso: MatCreate(), DASetLocalAdicMFFunction(), MatCreateDAAD()

460: @*/
461: PetscErrorCode  MatDAADSetDA(Mat A,DA da)
462: {
463:   PetscErrorCode ierr,(*f)(Mat,void*);

468:   PetscObjectQueryFunction((PetscObject)A,"MatDAADSetDA_C",(void (**)(void))&f);
469:   if (f) {
470:     (*f)(A,da);
471:   }
472:   return(0);
473: }

477: /*@C
478:    MatDAADSetSNES - Tells the matrix what SNES it is using for the base U.

480:    Collective on Mat and SNES

482:    Input Parameters:
483: +  mat - the matrix
484: -  snes - the SNES

486:    Level: intermediate

488:    Notes: this is currently turned off for Fortran usage

490: .seealso: MatCreate(), DASetLocalAdicMFFunction(), MatCreateDAAD(), MatDAADSetDA()

492: @*/
493: PetscErrorCode  MatDAADSetSNES(Mat A,SNES snes)
494: {
495:   PetscErrorCode ierr,(*f)(Mat,void*);

500:   PetscObjectQueryFunction((PetscObject)A,"MatDAADSetSNES_C",(void (**)(void))&f);
501:   if (f) {
502:     (*f)(A,snes);
503:   }
504:   return(0);
505: }

509: /*@C
510:    MatDAADSetCtx - Sets the user context for a DAAD (ADIC matrix-free) matrix.

512:    Collective on Mat

514:    Input Parameters:
515: +  mat - the matrix
516: -  ctx - the context

518:    Level: intermediate

520: .seealso: MatCreate(), DASetLocalAdicMFFunction(), MatCreateDAAD(), MatDAADSetDA()

522: @*/
523: PetscErrorCode  MatDAADSetCtx(Mat A,void *ctx)
524: {
525:   PetscErrorCode ierr,(*f)(Mat,void*);

529:   PetscObjectQueryFunction((PetscObject)A,"MatDAADSetCtx_C",(void (**)(void))&f);
530:   if (f) {
531:     (*f)(A,ctx);
532:   }
533:   return(0);
534: }

538: /*@C
539:    MatCreateDAAD - Creates a matrix that can do matrix-vector products using a local 
540:    function that is differentiated with ADIFOR or ADIC.

542:    Collective on DA

544:    Input Parameters:
545: .  da - the DA that defines the distribution of the vectors

547:    Output Parameter:
548: .  A - the matrix 

550:    Level: intermediate

552:    Notes: this is currently turned off for Fortran

554: .seealso: MatCreate(), DASetLocalAdicMFFunction()

556: @*/
557: PetscErrorCode  MatCreateDAAD(DA da,Mat *A)
558: {
560:   MPI_Comm comm;

563:   PetscObjectGetComm((PetscObject)da,&comm);
564:   MatCreate(comm,A);
565:   MatSetType(*A,MATDAAD);
566:   MatDAADSetDA(*A,da);
567:   return(0);
568: }


573: /*@
574:    MatRegisterDAAD - Registers DAAD matrix type

576:    Level: advanced

578: .seealso: MatCreateDAAD(), DASetLocalAdicMFFunction()

580: @*/
581: PetscErrorCode  MatRegisterDAAD(void)
582: {
585:   MatRegisterDynamic(MATDAAD,PETSC_NULL,"MatCreate_DAAD",MatCreate_DAAD);
586:   return(0);
587: }