xref: /petsc/src/ts/impls/implicit/radau5/radau5.c (revision e68ccae8c211ef21b0d8e1e4de86b470ac8cefa3)
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;
18*e68ccae8SBarry Smith   PetscErrorCode ierr;
196ffeb343SBarry Smith 
20*e68ccae8SBarry Smith   ierr = VecPlaceArray(cvode->work,Y);CHKERRABORT(PETSC_COMM_SELF,ierr);
21*e68ccae8SBarry Smith   ierr = VecPlaceArray(cvode->workf,F);CHKERRABORT(PETSC_COMM_SELF,ierr);
226ffeb343SBarry Smith 
236ffeb343SBarry Smith   /* Now compute the right hand side function, via IFunction unless only the more efficient RHSFunction is set */
24*e68ccae8SBarry Smith   ierr = TSGetDM(ts,&dm);CHKERRABORT(PETSC_COMM_SELF,ierr);
25*e68ccae8SBarry Smith   ierr = DMGetDMTS(dm,&tsdm);CHKERRABORT(PETSC_COMM_SELF,ierr);
26*e68ccae8SBarry Smith   ierr = DMTSGetIFunction(dm,&ifunction,NULL);CHKERRABORT(PETSC_COMM_SELF,ierr);
276ffeb343SBarry Smith   if (!ifunction) {
28*e68ccae8SBarry Smith     ierr = TSComputeRHSFunction(ts,*X,cvode->work,cvode->workf);CHKERRABORT(PETSC_COMM_SELF,ierr);
29*e68ccae8SBarry 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*e68ccae8SBarry Smith     ierr = VecDuplicate(cvode->work,&yydot);CHKERRABORT(PETSC_COMM_SELF,ierr);
33*e68ccae8SBarry Smith     ierr = VecZeroEntries(yydot);CHKERRABORT(PETSC_COMM_SELF,ierr);
34*e68ccae8SBarry Smith     ierr = TSComputeIFunction(ts,*X,cvode->work,yydot,cvode->workf,PETSC_FALSE);CHKERRABORT(PETSC_COMM_SELF,ierr);
35*e68ccae8SBarry Smith     ierr = VecScale(cvode->workf,-1.);CHKERRABORT(PETSC_COMM_SELF,ierr);
36*e68ccae8SBarry Smith     ierr = VecDestroy(&yydot);CHKERRABORT(PETSC_COMM_SELF,ierr);
376ffeb343SBarry Smith   }
386ffeb343SBarry Smith 
39*e68ccae8SBarry Smith   ierr = VecResetArray(cvode->work);CHKERRABORT(PETSC_COMM_SELF,ierr);
40*e68ccae8SBarry Smith   ierr = VecResetArray(cvode->workf);CHKERRABORT(PETSC_COMM_SELF,ierr);
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;
50*e68ccae8SBarry Smith   PetscErrorCode ierr;
51d249a78fSBarry Smith 
52*e68ccae8SBarry Smith   ierr = VecPlaceArray(cvode->work,Y);CHKERRABORT(PETSC_COMM_SELF,ierr);
53*e68ccae8SBarry Smith   ierr = VecDuplicate(cvode->work,&yydot);CHKERRABORT(PETSC_COMM_SELF,ierr);
54*e68ccae8SBarry Smith   ierr = VecGetSize(yydot,&n);CHKERRABORT(PETSC_COMM_SELF,ierr);
55*e68ccae8SBarry Smith   ierr = MatCreateSeqDense(PETSC_COMM_SELF,n,n,DFY,&mat);CHKERRABORT(PETSC_COMM_SELF,ierr);
56*e68ccae8SBarry Smith   ierr = VecZeroEntries(yydot);CHKERRABORT(PETSC_COMM_SELF,ierr);
57*e68ccae8SBarry Smith   ierr = TSComputeIJacobian(ts,*X,cvode->work,yydot,0,mat,mat,PETSC_FALSE);CHKERRABORT(PETSC_COMM_SELF,ierr);
58*e68ccae8SBarry Smith   ierr = MatScale(mat,-1.0);CHKERRABORT(PETSC_COMM_SELF,ierr);
59*e68ccae8SBarry Smith   ierr = MatDestroy(&mat);CHKERRABORT(PETSC_COMM_SELF,ierr);
60*e68ccae8SBarry Smith   ierr = VecDestroy(&yydot);CHKERRABORT(PETSC_COMM_SELF,ierr);
61*e68ccae8SBarry Smith   ierr = VecResetArray(cvode->work);CHKERRABORT(PETSC_COMM_SELF,ierr);
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;
68*e68ccae8SBarry Smith   PetscErrorCode ierr;
69d249a78fSBarry Smith 
70*e68ccae8SBarry Smith   ierr = VecPlaceArray(cvode->work,Y);CHKERRABORT(PETSC_COMM_SELF,ierr);
71d249a78fSBarry Smith   ts->time_step = *X - *XOLD;
72*e68ccae8SBarry Smith   ierr = TSMonitor(ts,*NR-1,*X,cvode->work);CHKERRABORT(PETSC_COMM_SELF,ierr);
73*e68ccae8SBarry Smith   ierr = VecResetArray(cvode->work);CHKERRABORT(PETSC_COMM_SELF,ierr);
74d249a78fSBarry Smith }
75d249a78fSBarry Smith 
76d249a78fSBarry Smith 
77d249a78fSBarry 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*);
78d249a78fSBarry Smith 
79d249a78fSBarry Smith PetscErrorCode TSSolve_Radau5(TS ts)
80d249a78fSBarry Smith {
81d249a78fSBarry Smith   TS_Radau5      *cvode = (TS_Radau5*)ts->data;
82d249a78fSBarry Smith   PetscErrorCode ierr;
83d249a78fSBarry Smith   PetscScalar    *Y,*WORK,X,XEND,RTOL,ATOL,H,RPAR;
84d249a78fSBarry Smith   PetscInt       ND,*IWORK,LWORK,LIWORK,MUJAC,MLMAS,MUMAS,IDID,ITOL;
85d249a78fSBarry Smith   int            IJAC,MLJAC,IMAS,IOUT;
86d249a78fSBarry Smith 
87d249a78fSBarry Smith   PetscFunctionBegin;
88d249a78fSBarry Smith   ierr = VecGetArray(ts->vec_sol,&Y);CHKERRQ(ierr);
89d249a78fSBarry Smith   ierr = VecGetSize(ts->vec_sol,&ND);CHKERRQ(ierr);
90d249a78fSBarry Smith   ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,ND,NULL,&cvode->work);CHKERRQ(ierr);
916ffeb343SBarry Smith   ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,ND,NULL,&cvode->workf);CHKERRQ(ierr);
92d249a78fSBarry Smith 
93d249a78fSBarry Smith   LWORK  = 4*ND*ND+12*ND+20;
94d249a78fSBarry Smith   LIWORK = 3*ND+20;
95d249a78fSBarry Smith 
96d249a78fSBarry Smith   ierr = PetscCalloc1(LWORK,&WORK);CHKERRQ(ierr);
97d249a78fSBarry Smith   ierr = PetscCalloc1(LIWORK,&IWORK);CHKERRQ(ierr);
98d249a78fSBarry Smith 
99d249a78fSBarry Smith   /* C --- PARAMETER IN THE DIFFERENTIAL EQUATION */
100d249a78fSBarry Smith   RPAR=1.0e-6;
101d249a78fSBarry Smith   /* C --- COMPUTE THE JACOBIAN ANALYTICALLY */
102d249a78fSBarry Smith   IJAC=1;
103d249a78fSBarry Smith   /* C --- JACOBIAN IS A FULL MATRIX */
104d249a78fSBarry Smith   MLJAC=ND;
105d249a78fSBarry Smith   /* C --- DIFFERENTIAL EQUATION IS IN EXPLICIT FORM*/
106d249a78fSBarry Smith   IMAS=0;
107d249a78fSBarry Smith   /* C --- OUTPUT ROUTINE IS USED DURING INTEGRATION*/
108d249a78fSBarry Smith   IOUT=1;
109d249a78fSBarry Smith   /* C --- INITIAL VALUES*/
110d249a78fSBarry Smith   X = ts->ptime;
111d249a78fSBarry Smith   /* C --- ENDPOINT OF INTEGRATION */
112d249a78fSBarry Smith   XEND = ts->max_time;
113d249a78fSBarry Smith   /* C --- REQUIRED TOLERANCE */
1146ffeb343SBarry Smith   RTOL = ts->rtol;
1156ffeb343SBarry Smith   ATOL = ts->atol;
116d249a78fSBarry Smith   ITOL=0;
117d249a78fSBarry Smith   /* C --- INITIAL STEP SIZE */
11869a506b1SBarry Smith   H = ts->time_step;
119d249a78fSBarry Smith 
120*e68ccae8SBarry Smith   /* output MUJAC MLMAS IDID; currently all ignored */
121d249a78fSBarry Smith 
122d249a78fSBarry 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);
123d249a78fSBarry Smith 
124d249a78fSBarry Smith   ierr = PetscFree(WORK);CHKERRQ(ierr);
125d249a78fSBarry Smith   ierr = PetscFree(IWORK);CHKERRQ(ierr);
126d249a78fSBarry Smith   PetscFunctionReturn(0);
127d249a78fSBarry Smith }
128d249a78fSBarry Smith 
129d249a78fSBarry Smith PetscErrorCode TSDestroy_Radau5(TS ts)
130d249a78fSBarry Smith {
131d249a78fSBarry Smith   TS_Radau5      *cvode = (TS_Radau5*)ts->data;
132d249a78fSBarry Smith   PetscErrorCode ierr;
133d249a78fSBarry Smith 
134d249a78fSBarry Smith   PetscFunctionBegin;
135d249a78fSBarry Smith   ierr = VecDestroy(&cvode->work);CHKERRQ(ierr);
1366ffeb343SBarry Smith   ierr = VecDestroy(&cvode->workf);CHKERRQ(ierr);
137d249a78fSBarry Smith   ierr = PetscFree(ts->data);CHKERRQ(ierr);
138d249a78fSBarry Smith   PetscFunctionReturn(0);
139d249a78fSBarry Smith }
140d249a78fSBarry Smith 
141d249a78fSBarry Smith /*MC
142d249a78fSBarry Smith       TSRADAU5 - ODE solver using the RADAU5 package
143d249a78fSBarry Smith 
144*e68ccae8SBarry Smith     Notes: This uses its own nonlinear solver and dense matrix direct solver so PETSc SNES and KSP options do not apply.
145*e68ccae8SBarry Smith            Uses its own time-step adaptivity (but uses the TS rtol and atol, and initial timestep)
146*e68ccae8SBarry Smith            Uses its own memory for the dense matrix storage and factorization
147*e68ccae8SBarry Smith            Can only handle ODEs of the form \cdot{u} = -F(t,u) + G(t,u)
148d249a78fSBarry Smith 
149d249a78fSBarry Smith     Level: beginner
150d249a78fSBarry Smith 
151*e68ccae8SBarry Smith .seealso:  TSCreate(), TS, TSSetType()
152d249a78fSBarry Smith 
153d249a78fSBarry Smith M*/
154d249a78fSBarry Smith PETSC_EXTERN PetscErrorCode TSCreate_Radau5(TS ts)
155d249a78fSBarry Smith {
156d249a78fSBarry Smith   TS_Radau5      *cvode;
157d249a78fSBarry Smith   PetscErrorCode ierr;
158d249a78fSBarry Smith 
159d249a78fSBarry Smith   PetscFunctionBegin;
160d249a78fSBarry Smith   ts->ops->destroy        = TSDestroy_Radau5;
161d249a78fSBarry Smith   ts->ops->solve          = TSSolve_Radau5;
162d249a78fSBarry Smith   ts->default_adapt_type  = TSADAPTNONE;
163d249a78fSBarry Smith 
164d249a78fSBarry Smith   ierr = PetscNewLog(ts,&cvode);CHKERRQ(ierr);
165d249a78fSBarry Smith   ts->data = (void*)cvode;
166d249a78fSBarry Smith   PetscFunctionReturn(0);
167d249a78fSBarry Smith }
168