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