xref: /petsc/src/ts/impls/implicit/radau5/radau5.c (revision f2300f31d01ffc99ca7a05a43941a14c1c1d9061)
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 
FVPOL(int * N,double * X,double * Y,double * F,double * RPAR,void * IPAR)1166976f2fSJacob Faibussowitsch static void FVPOL(int *N, double *X, double *Y, double *F, double *RPAR, void *IPAR)
12d71ae5a4SJacob Faibussowitsch {
136ffeb343SBarry Smith   TS             ts    = (TS)IPAR;
146ffeb343SBarry Smith   TS_Radau5     *cvode = (TS_Radau5 *)ts->data;
156ffeb343SBarry Smith   DM             dm;
166ffeb343SBarry Smith   DMTS           tsdm;
178434afd1SBarry Smith   TSIFunctionFn *ifunction;
186ffeb343SBarry Smith 
199566063dSJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, VecPlaceArray(cvode->work, Y));
209566063dSJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, VecPlaceArray(cvode->workf, F));
216ffeb343SBarry Smith 
22dd8e379bSPierre Jolivet   /* Now compute the right-hand side function, via IFunction unless only the more efficient RHSFunction is set */
239566063dSJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, TSGetDM(ts, &dm));
249566063dSJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, DMGetDMTS(dm, &tsdm));
259566063dSJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, DMTSGetIFunction(dm, &ifunction, NULL));
266ffeb343SBarry Smith   if (!ifunction) {
279566063dSJacob Faibussowitsch     PetscCallAbort(PETSC_COMM_SELF, TSComputeRHSFunction(ts, *X, cvode->work, cvode->workf));
28dd8e379bSPierre Jolivet   } else { /* If rhsfunction is also set, this computes both parts and scale them to the right-hand side */
296ffeb343SBarry Smith     Vec yydot;
306ffeb343SBarry Smith 
319566063dSJacob Faibussowitsch     PetscCallAbort(PETSC_COMM_SELF, VecDuplicate(cvode->work, &yydot));
329566063dSJacob Faibussowitsch     PetscCallAbort(PETSC_COMM_SELF, VecZeroEntries(yydot));
339566063dSJacob Faibussowitsch     PetscCallAbort(PETSC_COMM_SELF, TSComputeIFunction(ts, *X, cvode->work, yydot, cvode->workf, PETSC_FALSE));
349566063dSJacob Faibussowitsch     PetscCallAbort(PETSC_COMM_SELF, VecScale(cvode->workf, -1.));
359566063dSJacob Faibussowitsch     PetscCallAbort(PETSC_COMM_SELF, VecDestroy(&yydot));
366ffeb343SBarry Smith   }
376ffeb343SBarry Smith 
389566063dSJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, VecResetArray(cvode->work));
399566063dSJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, VecResetArray(cvode->workf));
406ffeb343SBarry Smith }
416ffeb343SBarry Smith 
JVPOL(PetscInt * N,PetscScalar * X,PetscScalar * Y,PetscScalar * DFY,int * LDFY,PetscScalar * RPAR,void * IPAR)4266976f2fSJacob Faibussowitsch static void JVPOL(PetscInt *N, PetscScalar *X, PetscScalar *Y, PetscScalar *DFY, int *LDFY, PetscScalar *RPAR, void *IPAR)
43d71ae5a4SJacob Faibussowitsch {
448acf3572SBarry Smith   TS         ts    = (TS)IPAR;
458acf3572SBarry Smith   TS_Radau5 *cvode = (TS_Radau5 *)ts->data;
468acf3572SBarry Smith   Vec        yydot;
478acf3572SBarry Smith   Mat        mat;
488acf3572SBarry Smith   PetscInt   n;
49d249a78fSBarry Smith 
509566063dSJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, VecPlaceArray(cvode->work, Y));
519566063dSJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, VecDuplicate(cvode->work, &yydot));
529566063dSJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, VecGetSize(yydot, &n));
539566063dSJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, MatCreateSeqDense(PETSC_COMM_SELF, n, n, DFY, &mat));
549566063dSJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, VecZeroEntries(yydot));
559566063dSJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, TSComputeIJacobian(ts, *X, cvode->work, yydot, 0, mat, mat, PETSC_FALSE));
569566063dSJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, MatScale(mat, -1.0));
579566063dSJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, MatDestroy(&mat));
589566063dSJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, VecDestroy(&yydot));
599566063dSJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, VecResetArray(cvode->work));
608acf3572SBarry Smith }
618acf3572SBarry Smith 
SOLOUT(int * NR,double * XOLD,double * X,double * Y,double * CONT,double * LRC,int * N,double * RPAR,void * IPAR,int * IRTRN)6266976f2fSJacob Faibussowitsch static void SOLOUT(int *NR, double *XOLD, double *X, double *Y, double *CONT, double *LRC, int *N, double *RPAR, void *IPAR, int *IRTRN)
63d71ae5a4SJacob Faibussowitsch {
64d249a78fSBarry Smith   TS         ts    = (TS)IPAR;
65d249a78fSBarry Smith   TS_Radau5 *cvode = (TS_Radau5 *)ts->data;
66d249a78fSBarry Smith 
679566063dSJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, VecPlaceArray(cvode->work, Y));
68d249a78fSBarry Smith   ts->time_step = *X - *XOLD;
699566063dSJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, TSMonitor(ts, *NR - 1, *X, cvode->work));
709566063dSJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, VecResetArray(cvode->work));
71d249a78fSBarry Smith }
72d249a78fSBarry Smith 
73*efa39862SBarry Smith extern 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 *);
74d249a78fSBarry Smith 
TSSolve_Radau5(TS ts)7566976f2fSJacob Faibussowitsch static PetscErrorCode TSSolve_Radau5(TS ts)
76d71ae5a4SJacob Faibussowitsch {
77d249a78fSBarry Smith   TS_Radau5   *cvode = (TS_Radau5 *)ts->data;
78d249a78fSBarry Smith   PetscScalar *Y, *WORK, X, XEND, RTOL, ATOL, H, RPAR;
79d249a78fSBarry Smith   PetscInt     ND, *IWORK, LWORK, LIWORK, MUJAC, MLMAS, MUMAS, IDID, ITOL;
80d249a78fSBarry Smith   int          IJAC, MLJAC, IMAS, IOUT;
81d249a78fSBarry Smith 
82d249a78fSBarry Smith   PetscFunctionBegin;
839566063dSJacob Faibussowitsch   PetscCall(VecGetArray(ts->vec_sol, &Y));
849566063dSJacob Faibussowitsch   PetscCall(VecGetSize(ts->vec_sol, &ND));
859566063dSJacob Faibussowitsch   PetscCall(VecCreateSeqWithArray(PETSC_COMM_SELF, 1, ND, NULL, &cvode->work));
869566063dSJacob Faibussowitsch   PetscCall(VecCreateSeqWithArray(PETSC_COMM_SELF, 1, ND, NULL, &cvode->workf));
87d249a78fSBarry Smith 
88d249a78fSBarry Smith   LWORK  = 4 * ND * ND + 12 * ND + 20;
89d249a78fSBarry Smith   LIWORK = 3 * ND + 20;
90d249a78fSBarry Smith 
919566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(LWORK, &WORK, LIWORK, &IWORK));
92d249a78fSBarry Smith 
93d249a78fSBarry Smith   /* C --- PARAMETER IN THE DIFFERENTIAL EQUATION */
94d249a78fSBarry Smith   RPAR = 1.0e-6;
95d249a78fSBarry Smith   /* C --- COMPUTE THE JACOBIAN ANALYTICALLY */
96d249a78fSBarry Smith   IJAC = 1;
97d249a78fSBarry Smith   /* C --- JACOBIAN IS A FULL MATRIX */
98d249a78fSBarry Smith   MLJAC = ND;
99d249a78fSBarry Smith   /* C --- DIFFERENTIAL EQUATION IS IN EXPLICIT FORM*/
100d249a78fSBarry Smith   IMAS = 0;
101d249a78fSBarry Smith   /* C --- OUTPUT ROUTINE IS USED DURING INTEGRATION*/
102d249a78fSBarry Smith   IOUT = 1;
103d249a78fSBarry Smith   /* C --- INITIAL VALUES*/
104d249a78fSBarry Smith   X = ts->ptime;
105d249a78fSBarry Smith   /* C --- ENDPOINT OF INTEGRATION */
106d249a78fSBarry Smith   XEND = ts->max_time;
107d249a78fSBarry Smith   /* C --- REQUIRED TOLERANCE */
1086ffeb343SBarry Smith   RTOL = ts->rtol;
1096ffeb343SBarry Smith   ATOL = ts->atol;
110d249a78fSBarry Smith   ITOL = 0;
111d249a78fSBarry Smith   /* C --- INITIAL STEP SIZE */
11269a506b1SBarry Smith   H = ts->time_step;
113d249a78fSBarry Smith 
114e68ccae8SBarry Smith   /* output MUJAC MLMAS IDID; currently all ignored */
115d249a78fSBarry Smith 
116d249a78fSBarry 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);
117d249a78fSBarry Smith 
1189566063dSJacob Faibussowitsch   PetscCall(PetscFree2(WORK, IWORK));
1193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
120d249a78fSBarry Smith }
121d249a78fSBarry Smith 
TSDestroy_Radau5(TS ts)12266976f2fSJacob Faibussowitsch static PetscErrorCode TSDestroy_Radau5(TS ts)
123d71ae5a4SJacob Faibussowitsch {
124d249a78fSBarry Smith   TS_Radau5 *cvode = (TS_Radau5 *)ts->data;
125d249a78fSBarry Smith 
126d249a78fSBarry Smith   PetscFunctionBegin;
1279566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&cvode->work));
1289566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&cvode->workf));
1299566063dSJacob Faibussowitsch   PetscCall(PetscFree(ts->data));
1303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
131d249a78fSBarry Smith }
132d249a78fSBarry Smith 
133d249a78fSBarry Smith /*MC
134bcf0153eSBarry Smith   TSRADAU5 - ODE solver using the external RADAU5 package, requires ./configure --download-radau5
135d249a78fSBarry Smith 
136d249a78fSBarry Smith   Level: beginner
137d249a78fSBarry Smith 
138bcf0153eSBarry Smith   Notes:
139bcf0153eSBarry Smith   This uses its own nonlinear solver and dense matrix direct solver so PETSc `SNES` and `KSP` options do not apply.
140d249a78fSBarry Smith 
141bcf0153eSBarry Smith   Uses its own time-step adaptivity (but uses the TS rtol and atol, and initial timestep)
142bcf0153eSBarry Smith 
143bcf0153eSBarry Smith   Uses its own memory for the dense matrix storage and factorization
144bcf0153eSBarry Smith 
145*efa39862SBarry Smith   Can only handle ODEs of the form $ \dot{u} = -F(t,u) + G(t,u) $
146bcf0153eSBarry Smith 
1471cc06b55SBarry Smith .seealso: [](ch_ts), `TSCreate()`, `TS`, `TSSetType()`, `TSType`
148d249a78fSBarry Smith M*/
TSCreate_Radau5(TS ts)149d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode TSCreate_Radau5(TS ts)
150d71ae5a4SJacob Faibussowitsch {
151d249a78fSBarry Smith   TS_Radau5 *cvode;
152d249a78fSBarry Smith 
153d249a78fSBarry Smith   PetscFunctionBegin;
154d249a78fSBarry Smith   ts->ops->destroy       = TSDestroy_Radau5;
155d249a78fSBarry Smith   ts->ops->solve         = TSSolve_Radau5;
156d249a78fSBarry Smith   ts->default_adapt_type = TSADAPTNONE;
157d249a78fSBarry Smith 
1584dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&cvode));
159d249a78fSBarry Smith   ts->data = (void *)cvode;
1603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
161d249a78fSBarry Smith }
162