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