static PetscErrorCode DMRestrictHook_TSTheta(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse,void *ctx) { TS ts = (TS)ctx; PetscErrorCode ierr; Vec X0,Xdot,X0_c,Xdot_c; PetscFunctionBegin; ierr = TSThetaGetX0AndXdot(ts,fine,&X0,&Xdot);CHKERRQ(ierr); ierr = TSThetaGetX0AndXdot(ts,coarse,&X0_c,&Xdot_c);CHKERRQ(ierr); ierr = MatRestrict(restrct,X0,X0_c);CHKERRQ(ierr); ierr = MatRestrict(restrct,Xdot,Xdot_c);CHKERRQ(ierr); ierr = VecPointwiseMult(X0_c,rscale,X0_c);CHKERRQ(ierr); ierr = VecPointwiseMult(Xdot_c,rscale,Xdot_c);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode DMSubDomainRestrictHook_TSTheta(DM dm,VecScatter gscat,VecScatter lscat,DM subdm,void *ctx) { TS ts = (TS)ctx; PetscErrorCode ierr; Vec X0,Xdot,X0_sub,Xdot_sub; PetscFunctionBegin; ierr = TSThetaGetX0AndXdot(ts,dm,&X0,&Xdot);CHKERRQ(ierr); ierr = TSThetaGetX0AndXdot(ts,subdm,&X0_sub,&Xdot_sub);CHKERRQ(ierr); ierr = VecScatterBegin(gscat,X0,X0_sub,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(gscat,X0,X0_sub,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterBegin(gscat,Xdot,Xdot_sub,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(gscat,Xdot,Xdot_sub,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = TSThetaRestoreX0AndXdot(ts,dm,&X0,&Xdot);CHKERRQ(ierr); ierr = TSThetaRestoreX0AndXdot(ts,subdm,&X0_sub,&Xdot_sub);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode SNESTSFormJacobian_Theta(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *str,TS ts) { TS_Theta *th = (TS_Theta*)ts->data; PetscErrorCode ierr; Vec Xdot; DM dm,dmsave; PetscFunctionBegin; ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); /* th->Xdot has already been computed in SNESTSFormFunction_Theta (SNES guarantees this) */ ierr = TSThetaGetX0AndXdot(ts,dm,PETSC_NULL,&Xdot);CHKERRQ(ierr); dmsave = ts->dm; ts->dm = dm; ierr = TSComputeIJacobian(ts,th->stage_time,x,Xdot,th->shift,A,B,str,PETSC_FALSE);CHKERRQ(ierr); ts->dm = dmsave; PetscFunctionReturn(0); }
static PetscErrorCode SNESTSFormJacobian_Theta(SNES snes,Vec x,Mat A,Mat B,TS ts) { TS_Theta *th = (TS_Theta*)ts->data; PetscErrorCode ierr; Vec Xdot; DM dm,dmsave; PetscReal shift = 1/(th->Theta*ts->time_step); PetscFunctionBegin; ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); /* Xdot has already been computed in SNESTSFormFunction_Theta (SNES guarantees this) */ ierr = TSThetaGetX0AndXdot(ts,dm,NULL,&Xdot);CHKERRQ(ierr); dmsave = ts->dm; ts->dm = dm; ierr = TSComputeIJacobian(ts,th->stage_time,x,Xdot,shift,A,B,PETSC_FALSE);CHKERRQ(ierr); ts->dm = dmsave; ierr = TSThetaRestoreX0AndXdot(ts,dm,NULL,&Xdot);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode SNESTSFormFunction_Theta(SNES snes,Vec x,Vec y,TS ts) { TS_Theta *th = (TS_Theta*)ts->data; PetscErrorCode ierr; Vec X0,Xdot; DM dm,dmsave; PetscFunctionBegin; ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); /* When using the endpoint variant, this is actually 1/Theta * Xdot */ ierr = TSThetaGetX0AndXdot(ts,dm,&X0,&Xdot);CHKERRQ(ierr); ierr = VecAXPBYPCZ(Xdot,-th->shift,th->shift,0,X0,x);CHKERRQ(ierr); /* DM monkey-business allows user code to call TSGetDM() inside of functions evaluated on levels of FAS */ dmsave = ts->dm; ts->dm = dm; ierr = TSComputeIFunction(ts,th->stage_time,x,Xdot,y,PETSC_FALSE);CHKERRQ(ierr); ts->dm = dmsave; PetscFunctionReturn(0); }