1d249a78fSBarry Smith /* 2d249a78fSBarry Smith Provides a PETSc interface to RADAU5 solver. 3d249a78fSBarry Smith 4d249a78fSBarry Smith */ 5d249a78fSBarry Smith #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/ 6d249a78fSBarry Smith 7d249a78fSBarry Smith typedef struct { 86ffeb343SBarry Smith Vec work,workf; 9d249a78fSBarry Smith } TS_Radau5; 10d249a78fSBarry Smith 11d249a78fSBarry Smith void FVPOL(int *N,double *X,double *Y,double *F,double *RPAR,void *IPAR) 12d249a78fSBarry Smith { 136ffeb343SBarry Smith TS ts = (TS) IPAR; 146ffeb343SBarry Smith TS_Radau5 *cvode = (TS_Radau5*)ts->data; 156ffeb343SBarry Smith DM dm; 166ffeb343SBarry Smith DMTS tsdm; 176ffeb343SBarry Smith TSIFunction ifunction; 18e68ccae8SBarry Smith PetscErrorCode ierr; 196ffeb343SBarry Smith 20*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,VecPlaceArray(cvode->work,Y)); 21*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,VecPlaceArray(cvode->workf,F)); 226ffeb343SBarry Smith 236ffeb343SBarry Smith /* Now compute the right hand side function, via IFunction unless only the more efficient RHSFunction is set */ 24*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,TSGetDM(ts,&dm)); 25*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,DMGetDMTS(dm,&tsdm)); 26*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,DMTSGetIFunction(dm,&ifunction,NULL)); 276ffeb343SBarry Smith if (!ifunction) { 28*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,TSComputeRHSFunction(ts,*X,cvode->work,cvode->workf)); 29e68ccae8SBarry Smith } else { /* If rhsfunction is also set, this computes both parts and scale them to the right hand side */ 306ffeb343SBarry Smith Vec yydot; 316ffeb343SBarry Smith 32*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,VecDuplicate(cvode->work,&yydot)); 33*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,VecZeroEntries(yydot)); 34*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,TSComputeIFunction(ts,*X,cvode->work,yydot,cvode->workf,PETSC_FALSE)); 35*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,VecScale(cvode->workf,-1.)); 36*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,VecDestroy(&yydot)); 376ffeb343SBarry Smith } 386ffeb343SBarry Smith 39*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,VecResetArray(cvode->work)); 40*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,VecResetArray(cvode->workf)); 416ffeb343SBarry Smith } 426ffeb343SBarry Smith 438acf3572SBarry Smith void JVPOL(PetscInt *N,PetscScalar *X,PetscScalar *Y,PetscScalar *DFY,int *LDFY,PetscScalar *RPAR,void *IPAR) 446ffeb343SBarry Smith { 458acf3572SBarry Smith TS ts = (TS) IPAR; 468acf3572SBarry Smith TS_Radau5 *cvode = (TS_Radau5*)ts->data; 478acf3572SBarry Smith Vec yydot; 488acf3572SBarry Smith Mat mat; 498acf3572SBarry Smith PetscInt n; 50e68ccae8SBarry Smith PetscErrorCode ierr; 51d249a78fSBarry Smith 52*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,VecPlaceArray(cvode->work,Y)); 53*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,VecDuplicate(cvode->work,&yydot)); 54*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,VecGetSize(yydot,&n)); 55*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,MatCreateSeqDense(PETSC_COMM_SELF,n,n,DFY,&mat)); 56*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,VecZeroEntries(yydot)); 57*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,TSComputeIJacobian(ts,*X,cvode->work,yydot,0,mat,mat,PETSC_FALSE)); 58*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,MatScale(mat,-1.0)); 59*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,MatDestroy(&mat)); 60*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,VecDestroy(&yydot)); 61*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,VecResetArray(cvode->work)); 628acf3572SBarry Smith } 638acf3572SBarry Smith 64d249a78fSBarry Smith void SOLOUT(int *NR,double *XOLD,double *X, double *Y,double *CONT,double *LRC,int *N,double *RPAR,void *IPAR,int *IRTRN) 65d249a78fSBarry Smith { 66d249a78fSBarry Smith TS ts = (TS) IPAR; 67d249a78fSBarry Smith TS_Radau5 *cvode = (TS_Radau5*)ts->data; 68e68ccae8SBarry Smith PetscErrorCode ierr; 69d249a78fSBarry Smith 70*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,VecPlaceArray(cvode->work,Y)); 71d249a78fSBarry Smith ts->time_step = *X - *XOLD; 72*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,TSMonitor(ts,*NR-1,*X,cvode->work)); 73*9566063dSJacob Faibussowitsch PetscCallAbort(PETSC_COMM_SELF,VecResetArray(cvode->work)); 74d249a78fSBarry Smith } 75d249a78fSBarry Smith 76d249a78fSBarry Smith void radau5_(int *,void*,double*,double*,double*,double*,double*,double*,int*,void*,int*,int*,int*,void*,int*,int*,int*,void*,int*,double*,int*,int*,int*,double*,void*,int*); 77d249a78fSBarry Smith 78d249a78fSBarry Smith PetscErrorCode TSSolve_Radau5(TS ts) 79d249a78fSBarry Smith { 80d249a78fSBarry Smith TS_Radau5 *cvode = (TS_Radau5*)ts->data; 81d249a78fSBarry Smith PetscErrorCode ierr; 82d249a78fSBarry Smith PetscScalar *Y,*WORK,X,XEND,RTOL,ATOL,H,RPAR; 83d249a78fSBarry Smith PetscInt ND,*IWORK,LWORK,LIWORK,MUJAC,MLMAS,MUMAS,IDID,ITOL; 84d249a78fSBarry Smith int IJAC,MLJAC,IMAS,IOUT; 85d249a78fSBarry Smith 86d249a78fSBarry Smith PetscFunctionBegin; 87*9566063dSJacob Faibussowitsch PetscCall(VecGetArray(ts->vec_sol,&Y)); 88*9566063dSJacob Faibussowitsch PetscCall(VecGetSize(ts->vec_sol,&ND)); 89*9566063dSJacob Faibussowitsch PetscCall(VecCreateSeqWithArray(PETSC_COMM_SELF,1,ND,NULL,&cvode->work)); 90*9566063dSJacob Faibussowitsch PetscCall(VecCreateSeqWithArray(PETSC_COMM_SELF,1,ND,NULL,&cvode->workf)); 91d249a78fSBarry Smith 92d249a78fSBarry Smith LWORK = 4*ND*ND+12*ND+20; 93d249a78fSBarry Smith LIWORK = 3*ND+20; 94d249a78fSBarry Smith 95*9566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(LWORK,&WORK,LIWORK,&IWORK)); 96d249a78fSBarry Smith 97d249a78fSBarry Smith /* C --- PARAMETER IN THE DIFFERENTIAL EQUATION */ 98d249a78fSBarry Smith RPAR=1.0e-6; 99d249a78fSBarry Smith /* C --- COMPUTE THE JACOBIAN ANALYTICALLY */ 100d249a78fSBarry Smith IJAC=1; 101d249a78fSBarry Smith /* C --- JACOBIAN IS A FULL MATRIX */ 102d249a78fSBarry Smith MLJAC=ND; 103d249a78fSBarry Smith /* C --- DIFFERENTIAL EQUATION IS IN EXPLICIT FORM*/ 104d249a78fSBarry Smith IMAS=0; 105d249a78fSBarry Smith /* C --- OUTPUT ROUTINE IS USED DURING INTEGRATION*/ 106d249a78fSBarry Smith IOUT=1; 107d249a78fSBarry Smith /* C --- INITIAL VALUES*/ 108d249a78fSBarry Smith X = ts->ptime; 109d249a78fSBarry Smith /* C --- ENDPOINT OF INTEGRATION */ 110d249a78fSBarry Smith XEND = ts->max_time; 111d249a78fSBarry Smith /* C --- REQUIRED TOLERANCE */ 1126ffeb343SBarry Smith RTOL = ts->rtol; 1136ffeb343SBarry Smith ATOL = ts->atol; 114d249a78fSBarry Smith ITOL=0; 115d249a78fSBarry Smith /* C --- INITIAL STEP SIZE */ 11669a506b1SBarry Smith H = ts->time_step; 117d249a78fSBarry Smith 118e68ccae8SBarry Smith /* output MUJAC MLMAS IDID; currently all ignored */ 119d249a78fSBarry Smith 120d249a78fSBarry Smith radau5_(&ND,FVPOL,&X,Y,&XEND,&H,&RTOL,&ATOL,&ITOL,JVPOL,&IJAC,&MLJAC,&MUJAC,FVPOL,&IMAS,&MLMAS,&MUMAS,SOLOUT,&IOUT,WORK,&LWORK,IWORK,&LIWORK,&RPAR,(void*)ts,&IDID); 121d249a78fSBarry Smith 122*9566063dSJacob Faibussowitsch PetscCall(PetscFree2(WORK,IWORK)); 123d249a78fSBarry Smith PetscFunctionReturn(0); 124d249a78fSBarry Smith } 125d249a78fSBarry Smith 126d249a78fSBarry Smith PetscErrorCode TSDestroy_Radau5(TS ts) 127d249a78fSBarry Smith { 128d249a78fSBarry Smith TS_Radau5 *cvode = (TS_Radau5*)ts->data; 129d249a78fSBarry Smith PetscErrorCode ierr; 130d249a78fSBarry Smith 131d249a78fSBarry Smith PetscFunctionBegin; 132*9566063dSJacob Faibussowitsch PetscCall(VecDestroy(&cvode->work)); 133*9566063dSJacob Faibussowitsch PetscCall(VecDestroy(&cvode->workf)); 134*9566063dSJacob Faibussowitsch PetscCall(PetscFree(ts->data)); 135d249a78fSBarry Smith PetscFunctionReturn(0); 136d249a78fSBarry Smith } 137d249a78fSBarry Smith 138d249a78fSBarry Smith /*MC 139d249a78fSBarry Smith TSRADAU5 - ODE solver using the RADAU5 package 140d249a78fSBarry Smith 14195452b02SPatrick Sanan Notes: 14295452b02SPatrick Sanan This uses its own nonlinear solver and dense matrix direct solver so PETSc SNES and KSP options do not apply. 143e68ccae8SBarry Smith Uses its own time-step adaptivity (but uses the TS rtol and atol, and initial timestep) 144e68ccae8SBarry Smith Uses its own memory for the dense matrix storage and factorization 145e68ccae8SBarry Smith Can only handle ODEs of the form \cdot{u} = -F(t,u) + G(t,u) 146d249a78fSBarry Smith 147d249a78fSBarry Smith Level: beginner 148d249a78fSBarry Smith 149e68ccae8SBarry Smith .seealso: TSCreate(), TS, TSSetType() 150d249a78fSBarry Smith 151d249a78fSBarry Smith M*/ 152d249a78fSBarry Smith PETSC_EXTERN PetscErrorCode TSCreate_Radau5(TS ts) 153d249a78fSBarry Smith { 154d249a78fSBarry Smith TS_Radau5 *cvode; 155d249a78fSBarry Smith PetscErrorCode ierr; 156d249a78fSBarry Smith 157d249a78fSBarry Smith PetscFunctionBegin; 158d249a78fSBarry Smith ts->ops->destroy = TSDestroy_Radau5; 159d249a78fSBarry Smith ts->ops->solve = TSSolve_Radau5; 160d249a78fSBarry Smith ts->default_adapt_type = TSADAPTNONE; 161d249a78fSBarry Smith 162*9566063dSJacob Faibussowitsch PetscCall(PetscNewLog(ts,&cvode)); 163d249a78fSBarry Smith ts->data = (void*)cvode; 164d249a78fSBarry Smith PetscFunctionReturn(0); 165d249a78fSBarry Smith } 166