xref: /petsc/src/ts/utils/dmdats.c (revision d2fc88d660d899f5d302fca28cab2ba057217d62)
124989b8cSPeter Brune #include <petscdmda.h>          /*I "petscdmda.h" I*/
2af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
3af0996ceSBarry Smith #include <petsc/private/tsimpl.h>   /*I "petscts.h" I*/
451b4a12fSMatthew G. Knepley #include <petscdraw.h>
524989b8cSPeter Brune 
624989b8cSPeter Brune /* This structure holds the user-provided DMDA callbacks */
724989b8cSPeter Brune typedef struct {
824989b8cSPeter Brune   PetscErrorCode (*ifunctionlocal)(DMDALocalInfo*,PetscReal,void*,void*,void*,void*);
924989b8cSPeter Brune   PetscErrorCode (*rhsfunctionlocal)(DMDALocalInfo*,PetscReal,void*,void*,void*);
10d1e9a80fSBarry Smith   PetscErrorCode (*ijacobianlocal)(DMDALocalInfo*,PetscReal,void*,void*,PetscReal,Mat,Mat,void*);
11d1e9a80fSBarry Smith   PetscErrorCode (*rhsjacobianlocal)(DMDALocalInfo*,PetscReal,void*,Mat,Mat,void*);
1224989b8cSPeter Brune   void       *ifunctionlocalctx;
1324989b8cSPeter Brune   void       *ijacobianlocalctx;
1424989b8cSPeter Brune   void       *rhsfunctionlocalctx;
1524989b8cSPeter Brune   void       *rhsjacobianlocalctx;
1624989b8cSPeter Brune   InsertMode ifunctionlocalimode;
1724989b8cSPeter Brune   InsertMode rhsfunctionlocalimode;
18942e3340SBarry Smith } DMTS_DA;
1924989b8cSPeter Brune 
20942e3340SBarry Smith static PetscErrorCode DMTSDestroy_DMDA(DMTS sdm)
2124989b8cSPeter Brune {
2224989b8cSPeter Brune   PetscErrorCode ierr;
2324989b8cSPeter Brune 
2424989b8cSPeter Brune   PetscFunctionBegin;
2524989b8cSPeter Brune   ierr = PetscFree(sdm->data);CHKERRQ(ierr);
2624989b8cSPeter Brune   PetscFunctionReturn(0);
2724989b8cSPeter Brune }
2824989b8cSPeter Brune 
29d74926cbSBarry Smith static PetscErrorCode DMTSDuplicate_DMDA(DMTS oldsdm,DMTS sdm)
300313d0e0SJed Brown {
310313d0e0SJed Brown   PetscErrorCode ierr;
320313d0e0SJed Brown 
330313d0e0SJed Brown   PetscFunctionBegin;
34b00a9115SJed Brown   ierr = PetscNewLog(sdm,(DMTS_DA**)&sdm->data);CHKERRQ(ierr);
35942e3340SBarry Smith   if (oldsdm->data) {ierr = PetscMemcpy(sdm->data,oldsdm->data,sizeof(DMTS_DA));CHKERRQ(ierr);}
360313d0e0SJed Brown   PetscFunctionReturn(0);
370313d0e0SJed Brown }
380313d0e0SJed Brown 
39942e3340SBarry Smith static PetscErrorCode DMDATSGetContext(DM dm,DMTS sdm,DMTS_DA **dmdats)
4024989b8cSPeter Brune {
4124989b8cSPeter Brune   PetscErrorCode ierr;
4224989b8cSPeter Brune 
4324989b8cSPeter Brune   PetscFunctionBegin;
440298fd71SBarry Smith   *dmdats = NULL;
4524989b8cSPeter Brune   if (!sdm->data) {
46b00a9115SJed Brown     ierr = PetscNewLog(dm,(DMTS_DA**)&sdm->data);CHKERRQ(ierr);
47d74926cbSBarry Smith     sdm->ops->destroy   = DMTSDestroy_DMDA;
48d74926cbSBarry Smith     sdm->ops->duplicate = DMTSDuplicate_DMDA;
4924989b8cSPeter Brune   }
50942e3340SBarry Smith   *dmdats = (DMTS_DA*)sdm->data;
5124989b8cSPeter Brune   PetscFunctionReturn(0);
5224989b8cSPeter Brune }
5324989b8cSPeter Brune 
5424989b8cSPeter Brune static PetscErrorCode TSComputeIFunction_DMDA(TS ts,PetscReal ptime,Vec X,Vec Xdot,Vec F,void *ctx)
5524989b8cSPeter Brune {
5624989b8cSPeter Brune   PetscErrorCode ierr;
5724989b8cSPeter Brune   DM             dm;
58942e3340SBarry Smith   DMTS_DA        *dmdats = (DMTS_DA*)ctx;
5924989b8cSPeter Brune   DMDALocalInfo  info;
60*d2fc88d6Ssepideh   Vec            Xloc,Xdotloc;
6124989b8cSPeter Brune   void           *x,*f,*xdot;
6224989b8cSPeter Brune 
6324989b8cSPeter Brune   PetscFunctionBegin;
6424989b8cSPeter Brune   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6524989b8cSPeter Brune   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
6624989b8cSPeter Brune   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
67ce94432eSBarry Smith   if (!dmdats->ifunctionlocal) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_PLIB,"Corrupt context");
6824989b8cSPeter Brune   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
69*d2fc88d6Ssepideh   ierr = DMGetLocalVector(dm,&Xdotloc);CHKERRQ(ierr);
70*d2fc88d6Ssepideh   ierr = DMGlobalToLocalBegin(dm,Xdot,INSERT_VALUES,Xdotloc);CHKERRQ(ierr);
71*d2fc88d6Ssepideh   ierr = DMGlobalToLocalEnd(dm,Xdot,INSERT_VALUES,Xdotloc);CHKERRQ(ierr);
7224989b8cSPeter Brune   ierr = DMGetLocalVector(dm,&Xloc);CHKERRQ(ierr);
7324989b8cSPeter Brune   ierr = DMGlobalToLocalBegin(dm,X,INSERT_VALUES,Xloc);CHKERRQ(ierr);
7424989b8cSPeter Brune   ierr = DMGlobalToLocalEnd(dm,X,INSERT_VALUES,Xloc);CHKERRQ(ierr);
7524989b8cSPeter Brune   ierr = DMDAGetLocalInfo(dm,&info);CHKERRQ(ierr);
7624989b8cSPeter Brune   ierr = DMDAVecGetArray(dm,Xloc,&x);CHKERRQ(ierr);
77*d2fc88d6Ssepideh   ierr = DMDAVecGetArray(dm,Xdotloc,&xdot);CHKERRQ(ierr);
7824989b8cSPeter Brune   switch (dmdats->ifunctionlocalimode) {
7924989b8cSPeter Brune   case INSERT_VALUES: {
8024989b8cSPeter Brune     ierr = DMDAVecGetArray(dm,F,&f);CHKERRQ(ierr);
8124989b8cSPeter Brune     CHKMEMQ;
8224989b8cSPeter Brune     ierr = (*dmdats->ifunctionlocal)(&info,ptime,x,xdot,f,dmdats->ifunctionlocalctx);CHKERRQ(ierr);
8324989b8cSPeter Brune     CHKMEMQ;
8424989b8cSPeter Brune     ierr = DMDAVecRestoreArray(dm,F,&f);CHKERRQ(ierr);
8524989b8cSPeter Brune   } break;
8624989b8cSPeter Brune   case ADD_VALUES: {
8724989b8cSPeter Brune     Vec Floc;
8824989b8cSPeter Brune     ierr = DMGetLocalVector(dm,&Floc);CHKERRQ(ierr);
8924989b8cSPeter Brune     ierr = VecZeroEntries(Floc);CHKERRQ(ierr);
9024989b8cSPeter Brune     ierr = DMDAVecGetArray(dm,Floc,&f);CHKERRQ(ierr);
9124989b8cSPeter Brune     CHKMEMQ;
9224989b8cSPeter Brune     ierr = (*dmdats->ifunctionlocal)(&info,ptime,x,xdot,f,dmdats->ifunctionlocalctx);CHKERRQ(ierr);
9324989b8cSPeter Brune     CHKMEMQ;
9424989b8cSPeter Brune     ierr = DMDAVecRestoreArray(dm,Floc,&f);CHKERRQ(ierr);
9524989b8cSPeter Brune     ierr = VecZeroEntries(F);CHKERRQ(ierr);
9624989b8cSPeter Brune     ierr = DMLocalToGlobalBegin(dm,Floc,ADD_VALUES,F);CHKERRQ(ierr);
9724989b8cSPeter Brune     ierr = DMLocalToGlobalEnd(dm,Floc,ADD_VALUES,F);CHKERRQ(ierr);
9824989b8cSPeter Brune     ierr = DMRestoreLocalVector(dm,&Floc);CHKERRQ(ierr);
9924989b8cSPeter Brune   } break;
100ce94432eSBarry Smith   default: SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_INCOMP,"Cannot use imode=%d",(int)dmdats->ifunctionlocalimode);
10124989b8cSPeter Brune   }
10224989b8cSPeter Brune   ierr = DMDAVecRestoreArray(dm,Xloc,&x);CHKERRQ(ierr);
10324989b8cSPeter Brune   ierr = DMRestoreLocalVector(dm,&Xloc);CHKERRQ(ierr);
104*d2fc88d6Ssepideh   ierr = DMDAVecRestoreArray(dm,Xdotloc,&xdot);CHKERRQ(ierr);
105*d2fc88d6Ssepideh   ierr = DMRestoreLocalVector(dm,&Xdotloc);CHKERRQ(ierr);
10624989b8cSPeter Brune   PetscFunctionReturn(0);
10724989b8cSPeter Brune }
10824989b8cSPeter Brune 
109d1e9a80fSBarry Smith static PetscErrorCode TSComputeIJacobian_DMDA(TS ts,PetscReal ptime,Vec X,Vec Xdot,PetscReal shift,Mat A,Mat B,void *ctx)
11024989b8cSPeter Brune {
11124989b8cSPeter Brune   PetscErrorCode ierr;
11224989b8cSPeter Brune   DM             dm;
113942e3340SBarry Smith   DMTS_DA        *dmdats = (DMTS_DA*)ctx;
11424989b8cSPeter Brune   DMDALocalInfo  info;
11524989b8cSPeter Brune   Vec            Xloc;
11624989b8cSPeter Brune   void           *x,*xdot;
11724989b8cSPeter Brune 
11824989b8cSPeter Brune   PetscFunctionBegin;
119ce94432eSBarry Smith   if (!dmdats->ifunctionlocal) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_PLIB,"Corrupt context");
12024989b8cSPeter Brune   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
12124989b8cSPeter Brune 
12224989b8cSPeter Brune   if (dmdats->ijacobianlocal) {
12324989b8cSPeter Brune     ierr = DMGetLocalVector(dm,&Xloc);CHKERRQ(ierr);
12424989b8cSPeter Brune     ierr = DMGlobalToLocalBegin(dm,X,INSERT_VALUES,Xloc);CHKERRQ(ierr);
12524989b8cSPeter Brune     ierr = DMGlobalToLocalEnd(dm,X,INSERT_VALUES,Xloc);CHKERRQ(ierr);
12624989b8cSPeter Brune     ierr = DMDAGetLocalInfo(dm,&info);CHKERRQ(ierr);
12724989b8cSPeter Brune     ierr = DMDAVecGetArray(dm,Xloc,&x);CHKERRQ(ierr);
12824989b8cSPeter Brune     ierr = DMDAVecGetArray(dm,Xdot,&xdot);CHKERRQ(ierr);
12924989b8cSPeter Brune     CHKMEMQ;
130d1e9a80fSBarry Smith     ierr = (*dmdats->ijacobianlocal)(&info,ptime,x,xdot,shift,A,B,dmdats->ijacobianlocalctx);CHKERRQ(ierr);
13124989b8cSPeter Brune     CHKMEMQ;
13224989b8cSPeter Brune     ierr = DMDAVecRestoreArray(dm,Xloc,&x);CHKERRQ(ierr);
13324989b8cSPeter Brune     ierr = DMDAVecRestoreArray(dm,Xdot,&xdot);CHKERRQ(ierr);
13424989b8cSPeter Brune     ierr = DMRestoreLocalVector(dm,&Xloc);CHKERRQ(ierr);
135ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_PLIB,"TSComputeIJacobian_DMDA() called without calling DMDATSSetIJacobian()");
13624989b8cSPeter Brune   /* This will be redundant if the user called both, but it's too common to forget. */
13794ab13aaSBarry Smith   if (A != B) {
13894ab13aaSBarry Smith     ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
13994ab13aaSBarry Smith     ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14024989b8cSPeter Brune   }
14124989b8cSPeter Brune   PetscFunctionReturn(0);
14224989b8cSPeter Brune }
14324989b8cSPeter Brune 
14424989b8cSPeter Brune static PetscErrorCode TSComputeRHSFunction_DMDA(TS ts,PetscReal ptime,Vec X,Vec F,void *ctx)
14524989b8cSPeter Brune {
14624989b8cSPeter Brune   PetscErrorCode ierr;
14724989b8cSPeter Brune   DM             dm;
148942e3340SBarry Smith   DMTS_DA        *dmdats = (DMTS_DA*)ctx;
14924989b8cSPeter Brune   DMDALocalInfo  info;
15024989b8cSPeter Brune   Vec            Xloc;
15124989b8cSPeter Brune   void           *x,*f;
15224989b8cSPeter Brune 
15324989b8cSPeter Brune   PetscFunctionBegin;
15424989b8cSPeter Brune   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
15524989b8cSPeter Brune   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
15624989b8cSPeter Brune   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
157ce94432eSBarry Smith   if (!dmdats->rhsfunctionlocal) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_PLIB,"Corrupt context");
15824989b8cSPeter Brune   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
15924989b8cSPeter Brune   ierr = DMGetLocalVector(dm,&Xloc);CHKERRQ(ierr);
16024989b8cSPeter Brune   ierr = DMGlobalToLocalBegin(dm,X,INSERT_VALUES,Xloc);CHKERRQ(ierr);
16124989b8cSPeter Brune   ierr = DMGlobalToLocalEnd(dm,X,INSERT_VALUES,Xloc);CHKERRQ(ierr);
16224989b8cSPeter Brune   ierr = DMDAGetLocalInfo(dm,&info);CHKERRQ(ierr);
16324989b8cSPeter Brune   ierr = DMDAVecGetArray(dm,Xloc,&x);CHKERRQ(ierr);
16424989b8cSPeter Brune   switch (dmdats->rhsfunctionlocalimode) {
16524989b8cSPeter Brune   case INSERT_VALUES: {
16624989b8cSPeter Brune     ierr = DMDAVecGetArray(dm,F,&f);CHKERRQ(ierr);
16724989b8cSPeter Brune     CHKMEMQ;
16824989b8cSPeter Brune     ierr = (*dmdats->rhsfunctionlocal)(&info,ptime,x,f,dmdats->rhsfunctionlocalctx);CHKERRQ(ierr);
16924989b8cSPeter Brune     CHKMEMQ;
17024989b8cSPeter Brune     ierr = DMDAVecRestoreArray(dm,F,&f);CHKERRQ(ierr);
17124989b8cSPeter Brune   } break;
17224989b8cSPeter Brune   case ADD_VALUES: {
17324989b8cSPeter Brune     Vec Floc;
17424989b8cSPeter Brune     ierr = DMGetLocalVector(dm,&Floc);CHKERRQ(ierr);
17524989b8cSPeter Brune     ierr = VecZeroEntries(Floc);CHKERRQ(ierr);
17624989b8cSPeter Brune     ierr = DMDAVecGetArray(dm,Floc,&f);CHKERRQ(ierr);
17724989b8cSPeter Brune     CHKMEMQ;
17824989b8cSPeter Brune     ierr = (*dmdats->rhsfunctionlocal)(&info,ptime,x,f,dmdats->rhsfunctionlocalctx);CHKERRQ(ierr);
17924989b8cSPeter Brune     CHKMEMQ;
18024989b8cSPeter Brune     ierr = DMDAVecRestoreArray(dm,Floc,&f);CHKERRQ(ierr);
18124989b8cSPeter Brune     ierr = VecZeroEntries(F);CHKERRQ(ierr);
18224989b8cSPeter Brune     ierr = DMLocalToGlobalBegin(dm,Floc,ADD_VALUES,F);CHKERRQ(ierr);
18324989b8cSPeter Brune     ierr = DMLocalToGlobalEnd(dm,Floc,ADD_VALUES,F);CHKERRQ(ierr);
18424989b8cSPeter Brune     ierr = DMRestoreLocalVector(dm,&Floc);CHKERRQ(ierr);
18524989b8cSPeter Brune   } break;
186ce94432eSBarry Smith   default: SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_INCOMP,"Cannot use imode=%d",(int)dmdats->rhsfunctionlocalimode);
18724989b8cSPeter Brune   }
18824989b8cSPeter Brune   ierr = DMDAVecRestoreArray(dm,Xloc,&x);CHKERRQ(ierr);
18924989b8cSPeter Brune   ierr = DMRestoreLocalVector(dm,&Xloc);CHKERRQ(ierr);
19024989b8cSPeter Brune   PetscFunctionReturn(0);
19124989b8cSPeter Brune }
19224989b8cSPeter Brune 
193d1e9a80fSBarry Smith static PetscErrorCode TSComputeRHSJacobian_DMDA(TS ts,PetscReal ptime,Vec X,Mat A,Mat B,void *ctx)
19424989b8cSPeter Brune {
19524989b8cSPeter Brune   PetscErrorCode ierr;
19624989b8cSPeter Brune   DM             dm;
197942e3340SBarry Smith   DMTS_DA        *dmdats = (DMTS_DA*)ctx;
19824989b8cSPeter Brune   DMDALocalInfo  info;
19924989b8cSPeter Brune   Vec            Xloc;
20024989b8cSPeter Brune   void           *x;
20124989b8cSPeter Brune 
20224989b8cSPeter Brune   PetscFunctionBegin;
203ce94432eSBarry Smith   if (!dmdats->rhsfunctionlocal) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_PLIB,"Corrupt context");
20424989b8cSPeter Brune   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
20524989b8cSPeter Brune 
20624989b8cSPeter Brune   if (dmdats->rhsjacobianlocal) {
20724989b8cSPeter Brune     ierr = DMGetLocalVector(dm,&Xloc);CHKERRQ(ierr);
20824989b8cSPeter Brune     ierr = DMGlobalToLocalBegin(dm,X,INSERT_VALUES,Xloc);CHKERRQ(ierr);
20924989b8cSPeter Brune     ierr = DMGlobalToLocalEnd(dm,X,INSERT_VALUES,Xloc);CHKERRQ(ierr);
21024989b8cSPeter Brune     ierr = DMDAGetLocalInfo(dm,&info);CHKERRQ(ierr);
21124989b8cSPeter Brune     ierr = DMDAVecGetArray(dm,Xloc,&x);CHKERRQ(ierr);
21224989b8cSPeter Brune     CHKMEMQ;
213d1e9a80fSBarry Smith     ierr = (*dmdats->rhsjacobianlocal)(&info,ptime,x,A,B,dmdats->rhsjacobianlocalctx);CHKERRQ(ierr);
21424989b8cSPeter Brune     CHKMEMQ;
21524989b8cSPeter Brune     ierr = DMDAVecRestoreArray(dm,Xloc,&x);CHKERRQ(ierr);
21624989b8cSPeter Brune     ierr = DMRestoreLocalVector(dm,&Xloc);CHKERRQ(ierr);
217ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_PLIB,"TSComputeRHSJacobian_DMDA() called without calling DMDATSSetRHSJacobian()");
21824989b8cSPeter Brune   /* This will be redundant if the user called both, but it's too common to forget. */
21994ab13aaSBarry Smith   if (A != B) {
22094ab13aaSBarry Smith     ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22194ab13aaSBarry Smith     ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22224989b8cSPeter Brune   }
22324989b8cSPeter Brune   PetscFunctionReturn(0);
22424989b8cSPeter Brune }
22524989b8cSPeter Brune 
22624989b8cSPeter Brune 
22724989b8cSPeter Brune /*@C
22824989b8cSPeter Brune    DMDATSSetRHSFunctionLocal - set a local residual evaluation function
22924989b8cSPeter Brune 
23024989b8cSPeter Brune    Logically Collective
23124989b8cSPeter Brune 
23224989b8cSPeter Brune    Input Arguments:
23324989b8cSPeter Brune +  dm - DM to associate callback with
234b398ffe5SPeter Brune .  imode - insert mode for the residual
23524989b8cSPeter Brune .  func - local residual evaluation
23624989b8cSPeter Brune -  ctx - optional context for local residual evaluation
23724989b8cSPeter Brune 
23824989b8cSPeter Brune    Calling sequence for func:
239b398ffe5SPeter Brune 
240b398ffe5SPeter Brune $ func(DMDALocalInfo info,PetscReal t,void *x,void *f,void *ctx)
241b398ffe5SPeter Brune 
24224989b8cSPeter Brune +  info - DMDALocalInfo defining the subdomain to evaluate the residual on
243b398ffe5SPeter Brune .  t - time at which to evaluate residual
244b398ffe5SPeter Brune .  x - array of local state information
245b398ffe5SPeter Brune .  f - output array of local residual information
246b398ffe5SPeter Brune -  ctx - optional user context
24724989b8cSPeter Brune 
24824989b8cSPeter Brune    Level: beginner
24924989b8cSPeter Brune 
2508e625dcfSPeter Brune .seealso: DMTSSetRHSFunction(), DMDATSSetRHSJacobianLocal(), DMDASNESSetFunctionLocal()
25124989b8cSPeter Brune @*/
2526c6b9e74SPeter Brune PetscErrorCode DMDATSSetRHSFunctionLocal(DM dm,InsertMode imode,DMDATSRHSFunctionLocal func,void *ctx)
25324989b8cSPeter Brune {
25424989b8cSPeter Brune   PetscErrorCode ierr;
255942e3340SBarry Smith   DMTS           sdm;
256942e3340SBarry Smith   DMTS_DA        *dmdats;
25724989b8cSPeter Brune 
25824989b8cSPeter Brune   PetscFunctionBegin;
25924989b8cSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
260942e3340SBarry Smith   ierr = DMGetDMTSWrite(dm,&sdm);CHKERRQ(ierr);
26124989b8cSPeter Brune   ierr = DMDATSGetContext(dm,sdm,&dmdats);CHKERRQ(ierr);
26224989b8cSPeter Brune   dmdats->rhsfunctionlocalimode = imode;
26324989b8cSPeter Brune   dmdats->rhsfunctionlocal      = func;
26424989b8cSPeter Brune   dmdats->rhsfunctionlocalctx   = ctx;
26524989b8cSPeter Brune   ierr = DMTSSetRHSFunction(dm,TSComputeRHSFunction_DMDA,dmdats);CHKERRQ(ierr);
26624989b8cSPeter Brune   PetscFunctionReturn(0);
26724989b8cSPeter Brune }
26824989b8cSPeter Brune 
26924989b8cSPeter Brune /*@C
27024989b8cSPeter Brune    DMDATSSetRHSJacobianLocal - set a local residual evaluation function
27124989b8cSPeter Brune 
27224989b8cSPeter Brune    Logically Collective
27324989b8cSPeter Brune 
27424989b8cSPeter Brune    Input Arguments:
27524989b8cSPeter Brune +  dm    - DM to associate callback with
276b398ffe5SPeter Brune .  func  - local RHS Jacobian evaluation routine
277b398ffe5SPeter Brune -  ctx   - optional context for local jacobian evaluation
27824989b8cSPeter Brune 
27924989b8cSPeter Brune    Calling sequence for func:
280b398ffe5SPeter Brune 
2817f6be190SBarry Smith $ func(DMDALocalInfo* info,PetscReal t,void* x,Mat J,Mat B,void *ctx);
282b398ffe5SPeter Brune 
28324989b8cSPeter Brune +  info - DMDALocalInfo defining the subdomain to evaluate the residual on
284b398ffe5SPeter Brune .  t    - time at which to evaluate residual
285b398ffe5SPeter Brune .  x    - array of local state information
286b398ffe5SPeter Brune .  J    - Jacobian matrix
287b398ffe5SPeter Brune .  B    - preconditioner matrix; often same as J
28824989b8cSPeter Brune -  ctx  - optional context passed above
28924989b8cSPeter Brune 
29024989b8cSPeter Brune    Level: beginner
29124989b8cSPeter Brune 
2928e625dcfSPeter Brune .seealso: DMTSSetRHSJacobian(), DMDATSSetRHSFunctionLocal(), DMDASNESSetJacobianLocal()
29324989b8cSPeter Brune @*/
2946c6b9e74SPeter Brune PetscErrorCode DMDATSSetRHSJacobianLocal(DM dm,DMDATSRHSJacobianLocal func,void *ctx)
29524989b8cSPeter Brune {
29624989b8cSPeter Brune   PetscErrorCode ierr;
297942e3340SBarry Smith   DMTS           sdm;
298942e3340SBarry Smith   DMTS_DA        *dmdats;
29924989b8cSPeter Brune 
30024989b8cSPeter Brune   PetscFunctionBegin;
30124989b8cSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
302942e3340SBarry Smith   ierr = DMGetDMTSWrite(dm,&sdm);CHKERRQ(ierr);
30324989b8cSPeter Brune   ierr = DMDATSGetContext(dm,sdm,&dmdats);CHKERRQ(ierr);
30424989b8cSPeter Brune   dmdats->rhsjacobianlocal    = func;
30524989b8cSPeter Brune   dmdats->rhsjacobianlocalctx = ctx;
30624989b8cSPeter Brune   ierr = DMTSSetRHSJacobian(dm,TSComputeRHSJacobian_DMDA,dmdats);CHKERRQ(ierr);
30724989b8cSPeter Brune   PetscFunctionReturn(0);
30824989b8cSPeter Brune }
30924989b8cSPeter Brune 
31024989b8cSPeter Brune 
31124989b8cSPeter Brune /*@C
31224989b8cSPeter Brune    DMDATSSetIFunctionLocal - set a local residual evaluation function
31324989b8cSPeter Brune 
31424989b8cSPeter Brune    Logically Collective
31524989b8cSPeter Brune 
31624989b8cSPeter Brune    Input Arguments:
31724989b8cSPeter Brune +  dm   - DM to associate callback with
31824989b8cSPeter Brune .  func - local residual evaluation
31924989b8cSPeter Brune -  ctx  - optional context for local residual evaluation
32024989b8cSPeter Brune 
32124989b8cSPeter Brune    Calling sequence for func:
32224989b8cSPeter Brune +  info - DMDALocalInfo defining the subdomain to evaluate the residual on
323b398ffe5SPeter Brune .  t    - time at which to evaluate residual
324b398ffe5SPeter Brune .  x    - array of local state information
325b398ffe5SPeter Brune .  xdot - array of local time derivative information
326b398ffe5SPeter Brune .  f    - output array of local function evaluation information
32724989b8cSPeter Brune -  ctx - optional context passed above
32824989b8cSPeter Brune 
32924989b8cSPeter Brune    Level: beginner
33024989b8cSPeter Brune 
3318e625dcfSPeter Brune .seealso: DMTSSetIFunction(), DMDATSSetIJacobianLocal(), DMDASNESSetFunctionLocal()
33224989b8cSPeter Brune @*/
3336c6b9e74SPeter Brune PetscErrorCode DMDATSSetIFunctionLocal(DM dm,InsertMode imode,DMDATSIFunctionLocal func,void *ctx)
33424989b8cSPeter Brune {
33524989b8cSPeter Brune   PetscErrorCode ierr;
336942e3340SBarry Smith   DMTS           sdm;
337942e3340SBarry Smith   DMTS_DA        *dmdats;
33824989b8cSPeter Brune 
33924989b8cSPeter Brune   PetscFunctionBegin;
34024989b8cSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
341942e3340SBarry Smith   ierr = DMGetDMTSWrite(dm,&sdm);CHKERRQ(ierr);
34224989b8cSPeter Brune   ierr = DMDATSGetContext(dm,sdm,&dmdats);CHKERRQ(ierr);
34324989b8cSPeter Brune   dmdats->ifunctionlocalimode = imode;
34424989b8cSPeter Brune   dmdats->ifunctionlocal      = func;
34524989b8cSPeter Brune   dmdats->ifunctionlocalctx   = ctx;
34624989b8cSPeter Brune   ierr = DMTSSetIFunction(dm,TSComputeIFunction_DMDA,dmdats);CHKERRQ(ierr);
34724989b8cSPeter Brune   PetscFunctionReturn(0);
34824989b8cSPeter Brune }
34924989b8cSPeter Brune 
35024989b8cSPeter Brune /*@C
35124989b8cSPeter Brune    DMDATSSetIJacobianLocal - set a local residual evaluation function
35224989b8cSPeter Brune 
35324989b8cSPeter Brune    Logically Collective
35424989b8cSPeter Brune 
35524989b8cSPeter Brune    Input Arguments:
35624989b8cSPeter Brune +  dm   - DM to associate callback with
35724989b8cSPeter Brune .  func - local residual evaluation
35824989b8cSPeter Brune -  ctx   - optional context for local residual evaluation
35924989b8cSPeter Brune 
36024989b8cSPeter Brune    Calling sequence for func:
361b398ffe5SPeter Brune 
362dab4423fSBarry Smith $ func(DMDALocalInfo* info,PetscReal t,void* x,void *xdot,PetscScalar shift,Mat J,Mat B,void *ctx);
363b398ffe5SPeter Brune 
36424989b8cSPeter Brune +  info - DMDALocalInfo defining the subdomain to evaluate the residual on
365b398ffe5SPeter Brune .  t    - time at which to evaluate the jacobian
366b398ffe5SPeter Brune .  x    - array of local state information
367b398ffe5SPeter Brune .  xdot - time derivative at this state
368dab4423fSBarry Smith .  shift - see TSSetIJacobian() for the meaning of this parameter
369b398ffe5SPeter Brune .  J    - Jacobian matrix
370b398ffe5SPeter Brune .  B    - preconditioner matrix; often same as J
37124989b8cSPeter Brune -  ctx  - optional context passed above
37224989b8cSPeter Brune 
37324989b8cSPeter Brune    Level: beginner
37424989b8cSPeter Brune 
3758e625dcfSPeter Brune .seealso: DMTSSetJacobian(), DMDATSSetIFunctionLocal(), DMDASNESSetJacobianLocal()
37624989b8cSPeter Brune @*/
3776c6b9e74SPeter Brune PetscErrorCode DMDATSSetIJacobianLocal(DM dm,DMDATSIJacobianLocal func,void *ctx)
37824989b8cSPeter Brune {
37924989b8cSPeter Brune   PetscErrorCode ierr;
380942e3340SBarry Smith   DMTS           sdm;
381942e3340SBarry Smith   DMTS_DA        *dmdats;
38224989b8cSPeter Brune 
38324989b8cSPeter Brune   PetscFunctionBegin;
38424989b8cSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
385942e3340SBarry Smith   ierr = DMGetDMTSWrite(dm,&sdm);CHKERRQ(ierr);
38624989b8cSPeter Brune   ierr = DMDATSGetContext(dm,sdm,&dmdats);CHKERRQ(ierr);
38724989b8cSPeter Brune   dmdats->ijacobianlocal    = func;
38824989b8cSPeter Brune   dmdats->ijacobianlocalctx = ctx;
38924989b8cSPeter Brune   ierr = DMTSSetIJacobian(dm,TSComputeIJacobian_DMDA,dmdats);CHKERRQ(ierr);
39024989b8cSPeter Brune   PetscFunctionReturn(0);
39124989b8cSPeter Brune }
392d1212d36SBarry Smith 
393d1212d36SBarry Smith PetscErrorCode TSMonitorDMDARayDestroy(void **mctx)
394d1212d36SBarry Smith {
395d1212d36SBarry Smith   TSMonitorDMDARayCtx *rayctx = (TSMonitorDMDARayCtx *) *mctx;
396d1212d36SBarry Smith   PetscErrorCode       ierr;
397d1212d36SBarry Smith 
398d1212d36SBarry Smith   PetscFunctionBegin;
39951b4a12fSMatthew G. Knepley   if (rayctx->lgctx) {ierr = TSMonitorLGCtxDestroy(&rayctx->lgctx);CHKERRQ(ierr);}
400d1212d36SBarry Smith   ierr = VecDestroy(&rayctx->ray);CHKERRQ(ierr);
401d1212d36SBarry Smith   ierr = VecScatterDestroy(&rayctx->scatter);CHKERRQ(ierr);
402d1212d36SBarry Smith   ierr = PetscViewerDestroy(&rayctx->viewer);CHKERRQ(ierr);
403d1212d36SBarry Smith   ierr = PetscFree(rayctx);CHKERRQ(ierr);
404d1212d36SBarry Smith   PetscFunctionReturn(0);
405d1212d36SBarry Smith }
406d1212d36SBarry Smith 
407d1212d36SBarry Smith PetscErrorCode TSMonitorDMDARay(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx)
408d1212d36SBarry Smith {
409d1212d36SBarry Smith   TSMonitorDMDARayCtx *rayctx = (TSMonitorDMDARayCtx*)mctx;
410d1212d36SBarry Smith   Vec                 solution;
411d1212d36SBarry Smith   PetscErrorCode      ierr;
412d1212d36SBarry Smith 
413d1212d36SBarry Smith   PetscFunctionBegin;
414d1212d36SBarry Smith   ierr = TSGetSolution(ts,&solution);CHKERRQ(ierr);
415d1212d36SBarry Smith   ierr = VecScatterBegin(rayctx->scatter,solution,rayctx->ray,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
416d1212d36SBarry Smith   ierr = VecScatterEnd(rayctx->scatter,solution,rayctx->ray,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
417d1212d36SBarry Smith   if (rayctx->viewer) {
418d1212d36SBarry Smith     ierr = VecView(rayctx->ray,rayctx->viewer);CHKERRQ(ierr);
419d1212d36SBarry Smith   }
420d1212d36SBarry Smith   PetscFunctionReturn(0);
421d1212d36SBarry Smith }
42251b4a12fSMatthew G. Knepley 
42351b4a12fSMatthew G. Knepley PetscErrorCode  TSMonitorLGDMDARay(TS ts, PetscInt step, PetscReal ptime, Vec u, void *ctx)
42451b4a12fSMatthew G. Knepley {
42551b4a12fSMatthew G. Knepley   TSMonitorDMDARayCtx *rayctx = (TSMonitorDMDARayCtx *) ctx;
42651b4a12fSMatthew G. Knepley   TSMonitorLGCtx       lgctx  = (TSMonitorLGCtx) rayctx->lgctx;
42751b4a12fSMatthew G. Knepley   Vec                  v      = rayctx->ray;
42851b4a12fSMatthew G. Knepley   const PetscScalar   *a;
42951b4a12fSMatthew G. Knepley   PetscInt             dim;
43051b4a12fSMatthew G. Knepley   PetscErrorCode       ierr;
43151b4a12fSMatthew G. Knepley 
43251b4a12fSMatthew G. Knepley   PetscFunctionBegin;
43351b4a12fSMatthew G. Knepley   ierr = VecScatterBegin(rayctx->scatter, u, v, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr);
43451b4a12fSMatthew G. Knepley   ierr = VecScatterEnd(rayctx->scatter, u, v, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr);
43551b4a12fSMatthew G. Knepley   if (!step) {
43651b4a12fSMatthew G. Knepley     PetscDrawAxis axis;
43751b4a12fSMatthew G. Knepley 
43851b4a12fSMatthew G. Knepley     ierr = PetscDrawLGGetAxis(lgctx->lg, &axis);CHKERRQ(ierr);
43951b4a12fSMatthew G. Knepley     ierr = PetscDrawAxisSetLabels(axis, "Solution Ray as function of time", "Time", "Solution");CHKERRQ(ierr);
44051b4a12fSMatthew G. Knepley     ierr = VecGetLocalSize(rayctx->ray, &dim);CHKERRQ(ierr);
44151b4a12fSMatthew G. Knepley     ierr = PetscDrawLGSetDimension(lgctx->lg, dim);CHKERRQ(ierr);
44251b4a12fSMatthew G. Knepley     ierr = PetscDrawLGReset(lgctx->lg);CHKERRQ(ierr);
44351b4a12fSMatthew G. Knepley   }
44451b4a12fSMatthew G. Knepley   ierr = VecGetArrayRead(v, &a);CHKERRQ(ierr);
44551b4a12fSMatthew G. Knepley #if defined(PETSC_USE_COMPLEX)
44651b4a12fSMatthew G. Knepley   {
44751b4a12fSMatthew G. Knepley     PetscReal *areal;
44851b4a12fSMatthew G. Knepley     PetscInt   i,n;
44951b4a12fSMatthew G. Knepley     ierr = VecGetLocalSize(v, &n);CHKERRQ(ierr);
450785e854fSJed Brown     ierr = PetscMalloc1(n, &areal);CHKERRQ(ierr);
45151b4a12fSMatthew G. Knepley     for (i = 0; i < n; ++i) areal[i] = PetscRealPart(a[i]);
45251b4a12fSMatthew G. Knepley     ierr = PetscDrawLGAddCommonPoint(lgctx->lg, ptime, areal);CHKERRQ(ierr);
45351b4a12fSMatthew G. Knepley     ierr = PetscFree(areal);CHKERRQ(ierr);
45451b4a12fSMatthew G. Knepley   }
45551b4a12fSMatthew G. Knepley #else
45651b4a12fSMatthew G. Knepley   ierr = PetscDrawLGAddCommonPoint(lgctx->lg, ptime, a);CHKERRQ(ierr);
45751b4a12fSMatthew G. Knepley #endif
45851b4a12fSMatthew G. Knepley   ierr = VecRestoreArrayRead(v, &a);CHKERRQ(ierr);
45951b4a12fSMatthew G. Knepley   if (((lgctx->howoften > 0) && (!(step % lgctx->howoften))) || ((lgctx->howoften == -1) && ts->reason)) {
46051b4a12fSMatthew G. Knepley     ierr = PetscDrawLGDraw(lgctx->lg);CHKERRQ(ierr);
4616934998bSLisandro Dalcin     ierr = PetscDrawLGSave(lgctx->lg);CHKERRQ(ierr);
46251b4a12fSMatthew G. Knepley   }
46351b4a12fSMatthew G. Knepley   PetscFunctionReturn(0);
46451b4a12fSMatthew G. Knepley }
465