xref: /petsc/src/ts/impls/implicit/radau5/radau5.c (revision 9566063d113dddea24716c546802770db7481bc0)
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