17cb94ee6SHong Zhang /* 2*bcf0153eSBarry Smith Provides a PETSc interface to version 2.5 of SUNDIALS/CVODE solver (a very old version) 37cb94ee6SHong Zhang The interface to PVODE (old version of CVODE) was originally contributed 47cb94ee6SHong Zhang by Liyang Xu. It has been redone by Hong Zhang and Dinesh Kaushik. 528adb3f7SHong Zhang 628adb3f7SHong Zhang Reference: sundials-2.4.0/examples/cvode/parallel/cvDiurnal_kry_p.c 77cb94ee6SHong Zhang */ 81c7d2463SJed Brown #include <../src/ts/impls/implicit/sundials/sundials.h> /*I "petscts.h" I*/ 97cb94ee6SHong Zhang 107cb94ee6SHong Zhang /* 117cb94ee6SHong Zhang TSPrecond_Sundials - function that we provide to SUNDIALS to 127cb94ee6SHong Zhang evaluate the preconditioner. 137cb94ee6SHong Zhang */ 14d71ae5a4SJacob Faibussowitsch PetscErrorCode TSPrecond_Sundials(realtype tn, N_Vector y, N_Vector fy, booleantype jok, booleantype *jcurPtr, realtype _gamma, void *P_data, N_Vector vtemp1, N_Vector vtemp2, N_Vector vtemp3) 15d71ae5a4SJacob Faibussowitsch { 167cb94ee6SHong Zhang TS ts = (TS)P_data; 177cb94ee6SHong Zhang TS_Sundials *cvode = (TS_Sundials *)ts->data; 18dcbc6d53SSean Farley PC pc; 190679a0aeSJed Brown Mat J, P; 200679a0aeSJed Brown Vec yy = cvode->w1, yydot = cvode->ydot; 210679a0aeSJed Brown PetscReal gm = (PetscReal)_gamma; 227cb94ee6SHong Zhang PetscScalar *y_data; 237cb94ee6SHong Zhang 247cb94ee6SHong Zhang PetscFunctionBegin; 259566063dSJacob Faibussowitsch PetscCall(TSGetIJacobian(ts, &J, &P, NULL, NULL)); 267cb94ee6SHong Zhang y_data = (PetscScalar *)N_VGetArrayPointer(y); 279566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(yy, y_data)); 289566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(yydot)); /* The Jacobian is independent of Ydot for ODE which is all that CVode works for */ 290679a0aeSJed Brown /* compute the shifted Jacobian (1/gm)*I + Jrest */ 309566063dSJacob Faibussowitsch PetscCall(TSComputeIJacobian(ts, ts->ptime, yy, yydot, 1 / gm, J, P, PETSC_FALSE)); 319566063dSJacob Faibussowitsch PetscCall(VecResetArray(yy)); 32*bcf0153eSBarry Smith PetscCall(MatScale(P, gm)); /* turn into I-gm*Jrest, J is not used by SUNDIALS */ 337cb94ee6SHong Zhang *jcurPtr = TRUE; 349566063dSJacob Faibussowitsch PetscCall(TSSundialsGetPC(ts, &pc)); 359566063dSJacob Faibussowitsch PetscCall(PCSetOperators(pc, J, P)); 367cb94ee6SHong Zhang PetscFunctionReturn(0); 377cb94ee6SHong Zhang } 387cb94ee6SHong Zhang 397cb94ee6SHong Zhang /* 40*bcf0153eSBarry Smith TSPSolve_Sundials - routine that we provide to SUNDIALS that applies the preconditioner. 417cb94ee6SHong Zhang */ 42d71ae5a4SJacob Faibussowitsch PetscErrorCode TSPSolve_Sundials(realtype tn, N_Vector y, N_Vector fy, N_Vector r, N_Vector z, realtype _gamma, realtype delta, int lr, void *P_data, N_Vector vtemp) 43d71ae5a4SJacob Faibussowitsch { 447cb94ee6SHong Zhang TS ts = (TS)P_data; 457cb94ee6SHong Zhang TS_Sundials *cvode = (TS_Sundials *)ts->data; 46dcbc6d53SSean Farley PC pc; 477cb94ee6SHong Zhang Vec rr = cvode->w1, zz = cvode->w2; 487cb94ee6SHong Zhang PetscScalar *r_data, *z_data; 497cb94ee6SHong Zhang 507cb94ee6SHong Zhang PetscFunctionBegin; 517cb94ee6SHong Zhang /* Make the PETSc work vectors rr and zz point to the arrays in the SUNDIALS vectors r and z respectively*/ 527cb94ee6SHong Zhang r_data = (PetscScalar *)N_VGetArrayPointer(r); 537cb94ee6SHong Zhang z_data = (PetscScalar *)N_VGetArrayPointer(z); 549566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(rr, r_data)); 559566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(zz, z_data)); 564ac7836bSHong Zhang 577cb94ee6SHong Zhang /* Solve the Px=r and put the result in zz */ 589566063dSJacob Faibussowitsch PetscCall(TSSundialsGetPC(ts, &pc)); 599566063dSJacob Faibussowitsch PetscCall(PCApply(pc, rr, zz)); 609566063dSJacob Faibussowitsch PetscCall(VecResetArray(rr)); 619566063dSJacob Faibussowitsch PetscCall(VecResetArray(zz)); 627cb94ee6SHong Zhang PetscFunctionReturn(0); 637cb94ee6SHong Zhang } 647cb94ee6SHong Zhang 657cb94ee6SHong Zhang /* 66*bcf0153eSBarry Smith TSFunction_Sundials - routine that we provide to SUNDIALS that applies the right hand side. 677cb94ee6SHong Zhang */ 68d71ae5a4SJacob Faibussowitsch int TSFunction_Sundials(realtype t, N_Vector y, N_Vector ydot, void *ctx) 69d71ae5a4SJacob Faibussowitsch { 707cb94ee6SHong Zhang TS ts = (TS)ctx; 715fcef5e4SJed Brown DM dm; 72942e3340SBarry Smith DMTS tsdm; 735fcef5e4SJed Brown TSIFunction ifunction; 74ce94432eSBarry Smith MPI_Comm comm; 757cb94ee6SHong Zhang TS_Sundials *cvode = (TS_Sundials *)ts->data; 760679a0aeSJed Brown Vec yy = cvode->w1, yyd = cvode->w2, yydot = cvode->ydot; 777cb94ee6SHong Zhang PetscScalar *y_data, *ydot_data; 787cb94ee6SHong Zhang 797cb94ee6SHong Zhang PetscFunctionBegin; 809566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)ts, &comm)); 815ff03cf7SDinesh Kaushik /* Make the PETSc work vectors yy and yyd point to the arrays in the SUNDIALS vectors y and ydot respectively*/ 827cb94ee6SHong Zhang y_data = (PetscScalar *)N_VGetArrayPointer(y); 837cb94ee6SHong Zhang ydot_data = (PetscScalar *)N_VGetArrayPointer(ydot); 849566063dSJacob Faibussowitsch PetscCallAbort(comm, VecPlaceArray(yy, y_data)); 859566063dSJacob Faibussowitsch PetscCallAbort(comm, VecPlaceArray(yyd, ydot_data)); 864ac7836bSHong Zhang 875fcef5e4SJed Brown /* Now compute the right hand side function, via IFunction unless only the more efficient RHSFunction is set */ 889566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &dm)); 899566063dSJacob Faibussowitsch PetscCall(DMGetDMTS(dm, &tsdm)); 909566063dSJacob Faibussowitsch PetscCall(DMTSGetIFunction(dm, &ifunction, NULL)); 915fcef5e4SJed Brown if (!ifunction) { 929566063dSJacob Faibussowitsch PetscCall(TSComputeRHSFunction(ts, t, yy, yyd)); 93bc0cc02bSJed Brown } else { /* If rhsfunction is also set, this computes both parts and shifts them to the right */ 949566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(yydot)); 959566063dSJacob Faibussowitsch PetscCallAbort(comm, TSComputeIFunction(ts, t, yy, yydot, yyd, PETSC_FALSE)); 969566063dSJacob Faibussowitsch PetscCall(VecScale(yyd, -1.)); 97bc0cc02bSJed Brown } 989566063dSJacob Faibussowitsch PetscCallAbort(comm, VecResetArray(yy)); 999566063dSJacob Faibussowitsch PetscCallAbort(comm, VecResetArray(yyd)); 1004ac7836bSHong Zhang PetscFunctionReturn(0); 1017cb94ee6SHong Zhang } 1027cb94ee6SHong Zhang 1037cb94ee6SHong Zhang /* 104*bcf0153eSBarry Smith TSStep_Sundials - Calls SUNDIALS to integrate the ODE. 1057cb94ee6SHong Zhang */ 106d71ae5a4SJacob Faibussowitsch PetscErrorCode TSStep_Sundials(TS ts) 107d71ae5a4SJacob Faibussowitsch { 1087cb94ee6SHong Zhang TS_Sundials *cvode = (TS_Sundials *)ts->data; 109b4eba00bSSean Farley PetscInt flag; 110be5899b3SLisandro Dalcin long int nits, lits, nsteps; 1117cb94ee6SHong Zhang realtype t, tout; 1127cb94ee6SHong Zhang PetscScalar *y_data; 1137cb94ee6SHong Zhang void *mem; 1147cb94ee6SHong Zhang 1157cb94ee6SHong Zhang PetscFunctionBegin; 11616016685SHong Zhang mem = cvode->mem; 1177cb94ee6SHong Zhang tout = ts->max_time; 1189566063dSJacob Faibussowitsch PetscCall(VecGetArray(ts->vec_sol, &y_data)); 1197cb94ee6SHong Zhang N_VSetArrayPointer((realtype *)y_data, cvode->y); 1209566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(ts->vec_sol, NULL)); 121186e87acSLisandro Dalcin 1229687d888SLisandro Dalcin /* We would like to TSPreStage() and TSPostStage() 1239687d888SLisandro Dalcin * before each stage solve but CVode does not appear to support this. */ 1249371c9d4SSatish Balay if (cvode->monitorstep) flag = CVode(mem, tout, cvode->y, &t, CV_ONE_STEP); 1259371c9d4SSatish Balay else flag = CVode(mem, tout, cvode->y, &t, CV_NORMAL); 1269f94935aSHong Zhang 1279f94935aSHong Zhang if (flag) { /* display error message */ 1289f94935aSHong Zhang switch (flag) { 129d71ae5a4SJacob Faibussowitsch case CV_ILL_INPUT: 130d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "CVode() fails, CV_ILL_INPUT"); 131d71ae5a4SJacob Faibussowitsch break; 132d71ae5a4SJacob Faibussowitsch case CV_TOO_CLOSE: 133d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "CVode() fails, CV_TOO_CLOSE"); 134d71ae5a4SJacob Faibussowitsch break; 1353c7fefeeSJed Brown case CV_TOO_MUCH_WORK: { 1369f94935aSHong Zhang PetscReal tcur; 1379566063dSJacob Faibussowitsch PetscCall(CVodeGetNumSteps(mem, &nsteps)); 1389566063dSJacob Faibussowitsch PetscCall(CVodeGetCurrentTime(mem, &tcur)); 13963a3b9bcSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "CVode() fails, CV_TOO_MUCH_WORK. At t=%g, nsteps %ld exceeds maxstep %" PetscInt_FMT ". Increase '-ts_max_steps <>' or modify TSSetMaxSteps()", (double)tcur, nsteps, ts->max_steps); 1403c7fefeeSJed Brown } break; 141d71ae5a4SJacob Faibussowitsch case CV_TOO_MUCH_ACC: 142d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "CVode() fails, CV_TOO_MUCH_ACC"); 143d71ae5a4SJacob Faibussowitsch break; 144d71ae5a4SJacob Faibussowitsch case CV_ERR_FAILURE: 145d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "CVode() fails, CV_ERR_FAILURE"); 146d71ae5a4SJacob Faibussowitsch break; 147d71ae5a4SJacob Faibussowitsch case CV_CONV_FAILURE: 148d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "CVode() fails, CV_CONV_FAILURE"); 149d71ae5a4SJacob Faibussowitsch break; 150d71ae5a4SJacob Faibussowitsch case CV_LINIT_FAIL: 151d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "CVode() fails, CV_LINIT_FAIL"); 152d71ae5a4SJacob Faibussowitsch break; 153d71ae5a4SJacob Faibussowitsch case CV_LSETUP_FAIL: 154d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "CVode() fails, CV_LSETUP_FAIL"); 155d71ae5a4SJacob Faibussowitsch break; 156d71ae5a4SJacob Faibussowitsch case CV_LSOLVE_FAIL: 157d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "CVode() fails, CV_LSOLVE_FAIL"); 158d71ae5a4SJacob Faibussowitsch break; 159d71ae5a4SJacob Faibussowitsch case CV_RHSFUNC_FAIL: 160d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "CVode() fails, CV_RHSFUNC_FAIL"); 161d71ae5a4SJacob Faibussowitsch break; 162d71ae5a4SJacob Faibussowitsch case CV_FIRST_RHSFUNC_ERR: 163d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "CVode() fails, CV_FIRST_RHSFUNC_ERR"); 164d71ae5a4SJacob Faibussowitsch break; 165d71ae5a4SJacob Faibussowitsch case CV_REPTD_RHSFUNC_ERR: 166d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "CVode() fails, CV_REPTD_RHSFUNC_ERR"); 167d71ae5a4SJacob Faibussowitsch break; 168d71ae5a4SJacob Faibussowitsch case CV_UNREC_RHSFUNC_ERR: 169d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "CVode() fails, CV_UNREC_RHSFUNC_ERR"); 170d71ae5a4SJacob Faibussowitsch break; 171d71ae5a4SJacob Faibussowitsch case CV_RTFUNC_FAIL: 172d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "CVode() fails, CV_RTFUNC_FAIL"); 173d71ae5a4SJacob Faibussowitsch break; 174d71ae5a4SJacob Faibussowitsch default: 175d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "CVode() fails, flag %d", flag); 1769f94935aSHong Zhang } 1779f94935aSHong Zhang } 1789f94935aSHong Zhang 179be5899b3SLisandro Dalcin /* log inner nonlinear and linear iterations */ 1809566063dSJacob Faibussowitsch PetscCall(CVodeGetNumNonlinSolvIters(mem, &nits)); 1819566063dSJacob Faibussowitsch PetscCall(CVSpilsGetNumLinIters(mem, &lits)); 1829371c9d4SSatish Balay ts->snes_its += nits; 1839371c9d4SSatish Balay ts->ksp_its = lits; 184be5899b3SLisandro Dalcin 1857cb94ee6SHong Zhang /* copy the solution from cvode->y to cvode->update and sol */ 1869566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(cvode->w1, y_data)); 1879566063dSJacob Faibussowitsch PetscCall(VecCopy(cvode->w1, cvode->update)); 1889566063dSJacob Faibussowitsch PetscCall(VecResetArray(cvode->w1)); 1899566063dSJacob Faibussowitsch PetscCall(VecCopy(cvode->update, ts->vec_sol)); 190186e87acSLisandro Dalcin 191186e87acSLisandro Dalcin ts->time_step = t - ts->ptime; 192186e87acSLisandro Dalcin ts->ptime = t; 193186e87acSLisandro Dalcin 1949566063dSJacob Faibussowitsch PetscCall(CVodeGetNumSteps(mem, &nsteps)); 1952808aa04SLisandro Dalcin if (!cvode->monitorstep) ts->steps += nsteps - 1; /* TSStep() increments the step counter by one */ 196b4eba00bSSean Farley PetscFunctionReturn(0); 197b4eba00bSSean Farley } 198b4eba00bSSean Farley 199d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSInterpolate_Sundials(TS ts, PetscReal t, Vec X) 200d71ae5a4SJacob Faibussowitsch { 201b4eba00bSSean Farley TS_Sundials *cvode = (TS_Sundials *)ts->data; 202b4eba00bSSean Farley N_Vector y; 203b4eba00bSSean Farley PetscScalar *x_data; 204b4eba00bSSean Farley PetscInt glosize, locsize; 205b4eba00bSSean Farley 206b4eba00bSSean Farley PetscFunctionBegin; 207b4eba00bSSean Farley /* get the vector size */ 2089566063dSJacob Faibussowitsch PetscCall(VecGetSize(X, &glosize)); 2099566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(X, &locsize)); 2109566063dSJacob Faibussowitsch PetscCall(VecGetArray(X, &x_data)); 211b4eba00bSSean Farley 2124d78c9e0SClaas Abert /* Initialize N_Vec y with x_data */ 213918687b8SPatrick Sanan if (cvode->use_dense) { 214918687b8SPatrick Sanan PetscMPIInt size; 215918687b8SPatrick Sanan 2169566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); 2173c633725SBarry Smith PetscCheck(size == 1, PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "TSSUNDIALS only supports a dense solve in the serial case"); 218918687b8SPatrick Sanan y = N_VMake_Serial(locsize, (realtype *)x_data); 219918687b8SPatrick Sanan } else { 2204d78c9e0SClaas Abert y = N_VMake_Parallel(cvode->comm_sundials, locsize, glosize, (realtype *)x_data); 221918687b8SPatrick Sanan } 222918687b8SPatrick Sanan 2233c633725SBarry Smith PetscCheck(y, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Interpolated y is not allocated"); 224b4eba00bSSean Farley 2259566063dSJacob Faibussowitsch PetscCall(CVodeGetDky(cvode->mem, t, 0, y)); 2269566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(X, &x_data)); 2277cb94ee6SHong Zhang PetscFunctionReturn(0); 2287cb94ee6SHong Zhang } 2297cb94ee6SHong Zhang 230d71ae5a4SJacob Faibussowitsch PetscErrorCode TSReset_Sundials(TS ts) 231d71ae5a4SJacob Faibussowitsch { 232277b19d0SLisandro Dalcin TS_Sundials *cvode = (TS_Sundials *)ts->data; 233277b19d0SLisandro Dalcin 234277b19d0SLisandro Dalcin PetscFunctionBegin; 2359566063dSJacob Faibussowitsch PetscCall(VecDestroy(&cvode->update)); 2369566063dSJacob Faibussowitsch PetscCall(VecDestroy(&cvode->ydot)); 2379566063dSJacob Faibussowitsch PetscCall(VecDestroy(&cvode->w1)); 2389566063dSJacob Faibussowitsch PetscCall(VecDestroy(&cvode->w2)); 239bbd56ea5SKarl Rupp if (cvode->mem) CVodeFree(&cvode->mem); 240277b19d0SLisandro Dalcin PetscFunctionReturn(0); 241277b19d0SLisandro Dalcin } 242277b19d0SLisandro Dalcin 243d71ae5a4SJacob Faibussowitsch PetscErrorCode TSDestroy_Sundials(TS ts) 244d71ae5a4SJacob Faibussowitsch { 2457cb94ee6SHong Zhang TS_Sundials *cvode = (TS_Sundials *)ts->data; 2467cb94ee6SHong Zhang 2477cb94ee6SHong Zhang PetscFunctionBegin; 2489566063dSJacob Faibussowitsch PetscCall(TSReset_Sundials(ts)); 2499566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_free(&(cvode->comm_sundials))); 2509566063dSJacob Faibussowitsch PetscCall(PetscFree(ts->data)); 2519566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsSetType_C", NULL)); 2529566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsSetMaxl_C", NULL)); 2539566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsSetLinearTolerance_C", NULL)); 2549566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsSetGramSchmidtType_C", NULL)); 2559566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsSetTolerance_C", NULL)); 2569566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsSetMinTimeStep_C", NULL)); 2579566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsSetMaxTimeStep_C", NULL)); 2589566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsGetPC_C", NULL)); 2599566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsGetIterations_C", NULL)); 2609566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsMonitorInternalSteps_C", NULL)); 2612e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsSetUseDense_C", NULL)); 2627cb94ee6SHong Zhang PetscFunctionReturn(0); 2637cb94ee6SHong Zhang } 2647cb94ee6SHong Zhang 265d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetUp_Sundials(TS ts) 266d71ae5a4SJacob Faibussowitsch { 2677cb94ee6SHong Zhang TS_Sundials *cvode = (TS_Sundials *)ts->data; 26816016685SHong Zhang PetscInt glosize, locsize, i, flag; 2697cb94ee6SHong Zhang PetscScalar *y_data, *parray; 27016016685SHong Zhang void *mem; 271dcbc6d53SSean Farley PC pc; 27219fd82e9SBarry Smith PCType pctype; 273ace3abfcSBarry Smith PetscBool pcnone; 2747cb94ee6SHong Zhang 2757cb94ee6SHong Zhang PetscFunctionBegin; 276*bcf0153eSBarry Smith PetscCheck(ts->exact_final_time != TS_EXACTFINALTIME_MATCHSTEP, PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for exact final time option 'MATCHSTEP' when using SUNDIALS"); 277236c45dcSShri Abhyankar 2787cb94ee6SHong Zhang /* get the vector size */ 2799566063dSJacob Faibussowitsch PetscCall(VecGetSize(ts->vec_sol, &glosize)); 2809566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(ts->vec_sol, &locsize)); 2817cb94ee6SHong Zhang 2827cb94ee6SHong Zhang /* allocate the memory for N_Vec y */ 283918687b8SPatrick Sanan if (cvode->use_dense) { 284918687b8SPatrick Sanan PetscMPIInt size; 285918687b8SPatrick Sanan 2869566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); 2873c633725SBarry Smith PetscCheck(size == 1, PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "TSSUNDIALS only supports a dense solve in the serial case"); 288918687b8SPatrick Sanan cvode->y = N_VNew_Serial(locsize); 289918687b8SPatrick Sanan } else { 290a07356b8SSatish Balay cvode->y = N_VNew_Parallel(cvode->comm_sundials, locsize, glosize); 291918687b8SPatrick Sanan } 2923c633725SBarry Smith PetscCheck(cvode->y, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "cvode->y is not allocated"); 2937cb94ee6SHong Zhang 29428adb3f7SHong Zhang /* initialize N_Vec y: copy ts->vec_sol to cvode->y */ 2959566063dSJacob Faibussowitsch PetscCall(VecGetArray(ts->vec_sol, &parray)); 2967cb94ee6SHong Zhang y_data = (PetscScalar *)N_VGetArrayPointer(cvode->y); 2977cb94ee6SHong Zhang for (i = 0; i < locsize; i++) y_data[i] = parray[i]; 2989566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(ts->vec_sol, NULL)); 29942528757SHong Zhang 3009566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &cvode->update)); 3019566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ts->vec_sol, &cvode->ydot)); 3027cb94ee6SHong Zhang 3037cb94ee6SHong Zhang /* 3047cb94ee6SHong Zhang Create work vectors for the TSPSolve_Sundials() routine. Note these are 3057cb94ee6SHong Zhang allocated with zero space arrays because the actual array space is provided 306*bcf0153eSBarry Smith by SUNDIALS and set using VecPlaceArray(). 3077cb94ee6SHong Zhang */ 3089566063dSJacob Faibussowitsch PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)ts), 1, locsize, PETSC_DECIDE, NULL, &cvode->w1)); 3099566063dSJacob Faibussowitsch PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)ts), 1, locsize, PETSC_DECIDE, NULL, &cvode->w2)); 31016016685SHong Zhang 31116016685SHong Zhang /* Call CVodeCreate to create the solver memory and the use of a Newton iteration */ 31216016685SHong Zhang mem = CVodeCreate(cvode->cvode_type, CV_NEWTON); 3133c633725SBarry Smith PetscCheck(mem, PETSC_COMM_SELF, PETSC_ERR_MEM, "CVodeCreate() fails"); 31416016685SHong Zhang cvode->mem = mem; 31516016685SHong Zhang 31616016685SHong Zhang /* Set the pointer to user-defined data */ 31716016685SHong Zhang flag = CVodeSetUserData(mem, ts); 31828b400f6SJacob Faibussowitsch PetscCheck(!flag, PETSC_COMM_SELF, PETSC_ERR_LIB, "CVodeSetUserData() fails"); 31916016685SHong Zhang 320*bcf0153eSBarry Smith /* SUNDIALS may choose to use a smaller initial step, but will never use a larger step. */ 321cdbf8f93SLisandro Dalcin flag = CVodeSetInitStep(mem, (realtype)ts->time_step); 32228b400f6SJacob Faibussowitsch PetscCheck(!flag, PetscObjectComm((PetscObject)ts), PETSC_ERR_LIB, "CVodeSetInitStep() failed"); 323f1cd61daSJed Brown if (cvode->mindt > 0) { 324f1cd61daSJed Brown flag = CVodeSetMinStep(mem, (realtype)cvode->mindt); 3259f94935aSHong Zhang if (flag) { 32608401ef6SPierre Jolivet PetscCheck(flag != CV_MEM_NULL, PetscObjectComm((PetscObject)ts), PETSC_ERR_LIB, "CVodeSetMinStep() failed, cvode_mem pointer is NULL"); 327f7d195e4SLawrence Mitchell PetscCheck(flag != CV_ILL_INPUT, PetscObjectComm((PetscObject)ts), PETSC_ERR_LIB, "CVodeSetMinStep() failed, hmin is nonpositive or it exceeds the maximum allowable step size"); 328f7d195e4SLawrence Mitchell SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_LIB, "CVodeSetMinStep() failed"); 3299f94935aSHong Zhang } 330f1cd61daSJed Brown } 331f1cd61daSJed Brown if (cvode->maxdt > 0) { 332f1cd61daSJed Brown flag = CVodeSetMaxStep(mem, (realtype)cvode->maxdt); 33328b400f6SJacob Faibussowitsch PetscCheck(!flag, PetscObjectComm((PetscObject)ts), PETSC_ERR_LIB, "CVodeSetMaxStep() failed"); 334f1cd61daSJed Brown } 335f1cd61daSJed Brown 33616016685SHong Zhang /* Call CVodeInit to initialize the integrator memory and specify the 337a5b23f4aSJose E. Roman * user's right hand side function in u'=f(t,u), the initial time T0, and 33816016685SHong Zhang * the initial dependent variable vector cvode->y */ 33916016685SHong Zhang flag = CVodeInit(mem, TSFunction_Sundials, ts->ptime, cvode->y); 34028b400f6SJacob Faibussowitsch PetscCheck(!flag, PETSC_COMM_SELF, PETSC_ERR_LIB, "CVodeInit() fails, flag %d", flag); 34116016685SHong Zhang 3429f94935aSHong Zhang /* specifies scalar relative and absolute tolerances */ 34316016685SHong Zhang flag = CVodeSStolerances(mem, cvode->reltol, cvode->abstol); 34428b400f6SJacob Faibussowitsch PetscCheck(!flag, PETSC_COMM_SELF, PETSC_ERR_LIB, "CVodeSStolerances() fails, flag %d", flag); 34516016685SHong Zhang 346c4e80e11SFlorian /* Specify max order of BDF / ADAMS method */ 347c4e80e11SFlorian if (cvode->maxord != PETSC_DEFAULT) { 348c4e80e11SFlorian flag = CVodeSetMaxOrd(mem, cvode->maxord); 34928b400f6SJacob Faibussowitsch PetscCheck(!flag, PETSC_COMM_SELF, PETSC_ERR_LIB, "CVodeSetMaxOrd() fails, flag %d", flag); 350c4e80e11SFlorian } 351c4e80e11SFlorian 3529f94935aSHong Zhang /* Specify max num of steps to be taken by cvode in its attempt to reach the next output time */ 3539f94935aSHong Zhang flag = CVodeSetMaxNumSteps(mem, ts->max_steps); 35428b400f6SJacob Faibussowitsch PetscCheck(!flag, PETSC_COMM_SELF, PETSC_ERR_LIB, "CVodeSetMaxNumSteps() fails, flag %d", flag); 35516016685SHong Zhang 356918687b8SPatrick Sanan if (cvode->use_dense) { 357918687b8SPatrick Sanan /* call CVDense to use a dense linear solver. */ 358918687b8SPatrick Sanan PetscMPIInt size; 359918687b8SPatrick Sanan 3609566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); 3613c633725SBarry Smith PetscCheck(size == 1, PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "TSSUNDIALS only supports a dense solve in the serial case"); 362918687b8SPatrick Sanan flag = CVDense(mem, locsize); 36328b400f6SJacob Faibussowitsch PetscCheck(!flag, PETSC_COMM_SELF, PETSC_ERR_LIB, "CVDense() fails, flag %d", flag); 364918687b8SPatrick Sanan } else { 36516016685SHong Zhang /* call CVSpgmr to use GMRES as the linear solver. */ 36616016685SHong Zhang /* setup the ode integrator with the given preconditioner */ 3679566063dSJacob Faibussowitsch PetscCall(TSSundialsGetPC(ts, &pc)); 3689566063dSJacob Faibussowitsch PetscCall(PCGetType(pc, &pctype)); 3699566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCNONE, &pcnone)); 37016016685SHong Zhang if (pcnone) { 37116016685SHong Zhang flag = CVSpgmr(mem, PREC_NONE, 0); 37228b400f6SJacob Faibussowitsch PetscCheck(!flag, PETSC_COMM_SELF, PETSC_ERR_LIB, "CVSpgmr() fails, flag %d", flag); 37316016685SHong Zhang } else { 374f61b2b6aSHong Zhang flag = CVSpgmr(mem, PREC_LEFT, cvode->maxl); 37528b400f6SJacob Faibussowitsch PetscCheck(!flag, PETSC_COMM_SELF, PETSC_ERR_LIB, "CVSpgmr() fails, flag %d", flag); 37616016685SHong Zhang 37716016685SHong Zhang /* Set preconditioner and solve routines Precond and PSolve, 37816016685SHong Zhang and the pointer to the user-defined block data */ 37916016685SHong Zhang flag = CVSpilsSetPreconditioner(mem, TSPrecond_Sundials, TSPSolve_Sundials); 38028b400f6SJacob Faibussowitsch PetscCheck(!flag, PETSC_COMM_SELF, PETSC_ERR_LIB, "CVSpilsSetPreconditioner() fails, flag %d", flag); 38116016685SHong Zhang } 382918687b8SPatrick Sanan } 3837cb94ee6SHong Zhang PetscFunctionReturn(0); 3847cb94ee6SHong Zhang } 3857cb94ee6SHong Zhang 3866fadb2cdSHong Zhang /* type of CVODE linear multistep method */ 387c793f718SLisandro Dalcin const char *const TSSundialsLmmTypes[] = {"", "ADAMS", "BDF", "TSSundialsLmmType", "SUNDIALS_", NULL}; 3886fadb2cdSHong Zhang /* type of G-S orthogonalization used by CVODE linear solver */ 389c793f718SLisandro Dalcin const char *const TSSundialsGramSchmidtTypes[] = {"", "MODIFIED", "CLASSICAL", "TSSundialsGramSchmidtType", "SUNDIALS_", NULL}; 390a04cf4d8SBarry Smith 391d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetFromOptions_Sundials(TS ts, PetscOptionItems *PetscOptionsObject) 392d71ae5a4SJacob Faibussowitsch { 3937cb94ee6SHong Zhang TS_Sundials *cvode = (TS_Sundials *)ts->data; 3947cb94ee6SHong Zhang int indx; 395ace3abfcSBarry Smith PetscBool flag; 3967bda3a07SJed Brown PC pc; 3977cb94ee6SHong Zhang 3987cb94ee6SHong Zhang PetscFunctionBegin; 399d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "SUNDIALS ODE solver options"); 4009566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-ts_sundials_type", "Scheme", "TSSundialsSetType", TSSundialsLmmTypes, 3, TSSundialsLmmTypes[cvode->cvode_type], &indx, &flag)); 4011baa6e33SBarry Smith if (flag) PetscCall(TSSundialsSetType(ts, (TSSundialsLmmType)indx)); 4029566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-ts_sundials_gramschmidt_type", "Type of orthogonalization", "TSSundialsSetGramSchmidtType", TSSundialsGramSchmidtTypes, 3, TSSundialsGramSchmidtTypes[cvode->gtype], &indx, &flag)); 4031baa6e33SBarry Smith if (flag) PetscCall(TSSundialsSetGramSchmidtType(ts, (TSSundialsGramSchmidtType)indx)); 4049566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-ts_sundials_atol", "Absolute tolerance for convergence", "TSSundialsSetTolerance", cvode->abstol, &cvode->abstol, NULL)); 4059566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-ts_sundials_rtol", "Relative tolerance for convergence", "TSSundialsSetTolerance", cvode->reltol, &cvode->reltol, NULL)); 4069566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-ts_sundials_mindt", "Minimum step size", "TSSundialsSetMinTimeStep", cvode->mindt, &cvode->mindt, NULL)); 4079566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-ts_sundials_maxdt", "Maximum step size", "TSSundialsSetMaxTimeStep", cvode->maxdt, &cvode->maxdt, NULL)); 4089566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-ts_sundials_linear_tolerance", "Convergence tolerance for linear solve", "TSSundialsSetLinearTolerance", cvode->linear_tol, &cvode->linear_tol, NULL)); 4099566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-ts_sundials_maxord", "Max Order for BDF/Adams method", "TSSundialsSetMaxOrd", cvode->maxord, &cvode->maxord, NULL)); 4109566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-ts_sundials_maxl", "Max dimension of the Krylov subspace", "TSSundialsSetMaxl", cvode->maxl, &cvode->maxl, NULL)); 4119566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-ts_sundials_monitor_steps", "Monitor SUNDIALS internal steps", "TSSundialsMonitorInternalSteps", cvode->monitorstep, &cvode->monitorstep, NULL)); 4129566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-ts_sundials_use_dense", "Use dense internal solver in SUNDIALS (serial only)", "TSSundialsSetUseDense", cvode->use_dense, &cvode->use_dense, NULL)); 413d0609cedSBarry Smith PetscOptionsHeadEnd(); 4149566063dSJacob Faibussowitsch PetscCall(TSSundialsGetPC(ts, &pc)); 4159566063dSJacob Faibussowitsch PetscCall(PCSetFromOptions(pc)); 4167cb94ee6SHong Zhang PetscFunctionReturn(0); 4177cb94ee6SHong Zhang } 4187cb94ee6SHong Zhang 419d71ae5a4SJacob Faibussowitsch PetscErrorCode TSView_Sundials(TS ts, PetscViewer viewer) 420d71ae5a4SJacob Faibussowitsch { 4217cb94ee6SHong Zhang TS_Sundials *cvode = (TS_Sundials *)ts->data; 4227cb94ee6SHong Zhang char *type; 4237cb94ee6SHong Zhang char atype[] = "Adams"; 4247cb94ee6SHong Zhang char btype[] = "BDF: backward differentiation formula"; 425ace3abfcSBarry Smith PetscBool iascii, isstring; 4262c823083SHong Zhang long int nsteps, its, nfevals, nlinsetups, nfails, itmp; 4272c823083SHong Zhang PetscInt qlast, qcur; 4285d47aee6SHong Zhang PetscReal hinused, hlast, hcur, tcur, tolsfac; 42942528757SHong Zhang PC pc; 4307cb94ee6SHong Zhang 4317cb94ee6SHong Zhang PetscFunctionBegin; 432bbd56ea5SKarl Rupp if (cvode->cvode_type == SUNDIALS_ADAMS) type = atype; 433bbd56ea5SKarl Rupp else type = btype; 4347cb94ee6SHong Zhang 4359566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 4369566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring)); 4377cb94ee6SHong Zhang if (iascii) { 438*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS integrator does not use SNES!\n")); 439*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS integrator type %s\n", type)); 440*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS maxord %" PetscInt_FMT "\n", cvode->maxord)); 441*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS abs tol %g rel tol %g\n", (double)cvode->abstol, (double)cvode->reltol)); 442918687b8SPatrick Sanan if (cvode->use_dense) { 443*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS integrator using a dense linear solve\n")); 444918687b8SPatrick Sanan } else { 445*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS linear solver tolerance factor %g\n", (double)cvode->linear_tol)); 446*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS max dimension of Krylov subspace %" PetscInt_FMT "\n", cvode->maxl)); 4477cb94ee6SHong Zhang if (cvode->gtype == SUNDIALS_MODIFIED_GS) { 448*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS using modified Gram-Schmidt for orthogonalization in GMRES\n")); 4497cb94ee6SHong Zhang } else { 450*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS using unmodified (classical) Gram-Schmidt for orthogonalization in GMRES\n")); 4517cb94ee6SHong Zhang } 452918687b8SPatrick Sanan } 453*bcf0153eSBarry Smith if (cvode->mindt > 0) PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS minimum time step %g\n", (double)cvode->mindt)); 454*bcf0153eSBarry Smith if (cvode->maxdt > 0) PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS maximum time step %g\n", (double)cvode->maxdt)); 4552c823083SHong Zhang 4565d47aee6SHong Zhang /* Outputs from CVODE, CVSPILS */ 4579566063dSJacob Faibussowitsch PetscCall(CVodeGetTolScaleFactor(cvode->mem, &tolsfac)); 458*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS suggested factor for tolerance scaling %g\n", tolsfac)); 4599566063dSJacob Faibussowitsch PetscCall(CVodeGetIntegratorStats(cvode->mem, &nsteps, &nfevals, &nlinsetups, &nfails, &qlast, &qcur, &hinused, &hlast, &hcur, &tcur)); 460*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS cumulative number of internal steps %ld\n", nsteps)); 461*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS no. of calls to rhs function %ld\n", nfevals)); 462*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS no. of calls to linear solver setup function %ld\n", nlinsetups)); 463*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS no. of error test failures %ld\n", nfails)); 4642c823083SHong Zhang 4659566063dSJacob Faibussowitsch PetscCall(CVodeGetNonlinSolvStats(cvode->mem, &its, &nfails)); 466*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS no. of nonlinear solver iterations %ld\n", its)); 467*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS no. of nonlinear convergence failure %ld\n", nfails)); 468918687b8SPatrick Sanan if (!cvode->use_dense) { 4699566063dSJacob Faibussowitsch PetscCall(CVSpilsGetNumLinIters(cvode->mem, &its)); /* its = no. of calls to TSPrecond_Sundials() */ 470*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS no. of linear iterations %ld\n", its)); 4719566063dSJacob Faibussowitsch PetscCall(CVSpilsGetNumConvFails(cvode->mem, &itmp)); 472*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS no. of linear convergence failures %ld\n", itmp)); 47342528757SHong Zhang 4749566063dSJacob Faibussowitsch PetscCall(TSSundialsGetPC(ts, &pc)); 4759566063dSJacob Faibussowitsch PetscCall(PCView(pc, viewer)); 4769566063dSJacob Faibussowitsch PetscCall(CVSpilsGetNumPrecEvals(cvode->mem, &itmp)); 477*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS no. of preconditioner evaluations %ld\n", itmp)); 4789566063dSJacob Faibussowitsch PetscCall(CVSpilsGetNumPrecSolves(cvode->mem, &itmp)); 479*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS no. of preconditioner solves %ld\n", itmp)); 480918687b8SPatrick Sanan } 4819566063dSJacob Faibussowitsch PetscCall(CVSpilsGetNumJtimesEvals(cvode->mem, &itmp)); 482*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS no. of Jacobian-vector product evaluations %ld\n", itmp)); 4839566063dSJacob Faibussowitsch PetscCall(CVSpilsGetNumRhsEvals(cvode->mem, &itmp)); 484*bcf0153eSBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "SUNDIALS no. of rhs calls for finite diff. Jacobian-vector evals %ld\n", itmp)); 4857cb94ee6SHong Zhang } else if (isstring) { 486*bcf0153eSBarry Smith PetscCall(PetscViewerStringSPrintf(viewer, "SUNDIALS type %s", type)); 4877cb94ee6SHong Zhang } 4887cb94ee6SHong Zhang PetscFunctionReturn(0); 4897cb94ee6SHong Zhang } 4907cb94ee6SHong Zhang 4917cb94ee6SHong Zhang /* --------------------------------------------------------------------------*/ 492d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsSetType_Sundials(TS ts, TSSundialsLmmType type) 493d71ae5a4SJacob Faibussowitsch { 4947cb94ee6SHong Zhang TS_Sundials *cvode = (TS_Sundials *)ts->data; 4957cb94ee6SHong Zhang 4967cb94ee6SHong Zhang PetscFunctionBegin; 4977cb94ee6SHong Zhang cvode->cvode_type = type; 4987cb94ee6SHong Zhang PetscFunctionReturn(0); 4997cb94ee6SHong Zhang } 5007cb94ee6SHong Zhang 501d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsSetMaxl_Sundials(TS ts, PetscInt maxl) 502d71ae5a4SJacob Faibussowitsch { 5037cb94ee6SHong Zhang TS_Sundials *cvode = (TS_Sundials *)ts->data; 5047cb94ee6SHong Zhang 5057cb94ee6SHong Zhang PetscFunctionBegin; 506f61b2b6aSHong Zhang cvode->maxl = maxl; 5077cb94ee6SHong Zhang PetscFunctionReturn(0); 5087cb94ee6SHong Zhang } 5097cb94ee6SHong Zhang 510d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsSetLinearTolerance_Sundials(TS ts, PetscReal tol) 511d71ae5a4SJacob Faibussowitsch { 5127cb94ee6SHong Zhang TS_Sundials *cvode = (TS_Sundials *)ts->data; 5137cb94ee6SHong Zhang 5147cb94ee6SHong Zhang PetscFunctionBegin; 5157cb94ee6SHong Zhang cvode->linear_tol = tol; 5167cb94ee6SHong Zhang PetscFunctionReturn(0); 5177cb94ee6SHong Zhang } 5187cb94ee6SHong Zhang 519d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsSetGramSchmidtType_Sundials(TS ts, TSSundialsGramSchmidtType type) 520d71ae5a4SJacob Faibussowitsch { 5217cb94ee6SHong Zhang TS_Sundials *cvode = (TS_Sundials *)ts->data; 5227cb94ee6SHong Zhang 5237cb94ee6SHong Zhang PetscFunctionBegin; 5247cb94ee6SHong Zhang cvode->gtype = type; 5257cb94ee6SHong Zhang PetscFunctionReturn(0); 5267cb94ee6SHong Zhang } 5277cb94ee6SHong Zhang 528d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsSetTolerance_Sundials(TS ts, PetscReal aabs, PetscReal rel) 529d71ae5a4SJacob Faibussowitsch { 5307cb94ee6SHong Zhang TS_Sundials *cvode = (TS_Sundials *)ts->data; 5317cb94ee6SHong Zhang 5327cb94ee6SHong Zhang PetscFunctionBegin; 5337cb94ee6SHong Zhang if (aabs != PETSC_DECIDE) cvode->abstol = aabs; 5347cb94ee6SHong Zhang if (rel != PETSC_DECIDE) cvode->reltol = rel; 5357cb94ee6SHong Zhang PetscFunctionReturn(0); 5367cb94ee6SHong Zhang } 5377cb94ee6SHong Zhang 538d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsSetMinTimeStep_Sundials(TS ts, PetscReal mindt) 539d71ae5a4SJacob Faibussowitsch { 540f1cd61daSJed Brown TS_Sundials *cvode = (TS_Sundials *)ts->data; 541f1cd61daSJed Brown 542f1cd61daSJed Brown PetscFunctionBegin; 543f1cd61daSJed Brown cvode->mindt = mindt; 544f1cd61daSJed Brown PetscFunctionReturn(0); 545f1cd61daSJed Brown } 546f1cd61daSJed Brown 547d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsSetMaxTimeStep_Sundials(TS ts, PetscReal maxdt) 548d71ae5a4SJacob Faibussowitsch { 549f1cd61daSJed Brown TS_Sundials *cvode = (TS_Sundials *)ts->data; 550f1cd61daSJed Brown 551f1cd61daSJed Brown PetscFunctionBegin; 552f1cd61daSJed Brown cvode->maxdt = maxdt; 553f1cd61daSJed Brown PetscFunctionReturn(0); 554f1cd61daSJed Brown } 555918687b8SPatrick Sanan 556d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsSetUseDense_Sundials(TS ts, PetscBool use_dense) 557d71ae5a4SJacob Faibussowitsch { 558918687b8SPatrick Sanan TS_Sundials *cvode = (TS_Sundials *)ts->data; 559918687b8SPatrick Sanan 560918687b8SPatrick Sanan PetscFunctionBegin; 561918687b8SPatrick Sanan cvode->use_dense = use_dense; 562918687b8SPatrick Sanan PetscFunctionReturn(0); 563918687b8SPatrick Sanan } 564918687b8SPatrick Sanan 565d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsGetPC_Sundials(TS ts, PC *pc) 566d71ae5a4SJacob Faibussowitsch { 567dcbc6d53SSean Farley SNES snes; 568dcbc6d53SSean Farley KSP ksp; 5697cb94ee6SHong Zhang 5707cb94ee6SHong Zhang PetscFunctionBegin; 5719566063dSJacob Faibussowitsch PetscCall(TSGetSNES(ts, &snes)); 5729566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 5739566063dSJacob Faibussowitsch PetscCall(KSPGetPC(ksp, pc)); 5747cb94ee6SHong Zhang PetscFunctionReturn(0); 5757cb94ee6SHong Zhang } 5767cb94ee6SHong Zhang 577d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsGetIterations_Sundials(TS ts, int *nonlin, int *lin) 578d71ae5a4SJacob Faibussowitsch { 5797cb94ee6SHong Zhang PetscFunctionBegin; 5805ef26d82SJed Brown if (nonlin) *nonlin = ts->snes_its; 5815ef26d82SJed Brown if (lin) *lin = ts->ksp_its; 5827cb94ee6SHong Zhang PetscFunctionReturn(0); 5837cb94ee6SHong Zhang } 5847cb94ee6SHong Zhang 585d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsMonitorInternalSteps_Sundials(TS ts, PetscBool s) 586d71ae5a4SJacob Faibussowitsch { 5872bfc04deSHong Zhang TS_Sundials *cvode = (TS_Sundials *)ts->data; 5882bfc04deSHong Zhang 5892bfc04deSHong Zhang PetscFunctionBegin; 5902bfc04deSHong Zhang cvode->monitorstep = s; 5912bfc04deSHong Zhang PetscFunctionReturn(0); 5922bfc04deSHong Zhang } 5937cb94ee6SHong Zhang /* -------------------------------------------------------------------------------------------*/ 5947cb94ee6SHong Zhang 5957cb94ee6SHong Zhang /*@C 596*bcf0153eSBarry Smith TSSundialsGetIterations - Gets the number of nonlinear and linear iterations used so far by `TSSUNDIALS`. 5977cb94ee6SHong Zhang 5987cb94ee6SHong Zhang Not Collective 5997cb94ee6SHong Zhang 60097bb3fdcSJose E. Roman Input Parameter: 6017cb94ee6SHong Zhang . ts - the time-step context 6027cb94ee6SHong Zhang 6037cb94ee6SHong Zhang Output Parameters: 6047cb94ee6SHong Zhang + nonlin - number of nonlinear iterations 6057cb94ee6SHong Zhang - lin - number of linear iterations 6067cb94ee6SHong Zhang 6077cb94ee6SHong Zhang Level: advanced 6087cb94ee6SHong Zhang 609*bcf0153eSBarry Smith Note: 610*bcf0153eSBarry Smith These return the number since the creation of the `TS` object 6117cb94ee6SHong Zhang 612*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSSundialsSetType()`, `TSSundialsSetMaxl()`, 613db781477SPatrick Sanan `TSSundialsSetLinearTolerance()`, `TSSundialsSetGramSchmidtType()`, `TSSundialsSetTolerance()`, 614db781477SPatrick Sanan `TSSundialsGetIterations()`, `TSSundialsSetType()`, 615db781477SPatrick Sanan `TSSundialsSetLinearTolerance()`, `TSSundialsGetPC()`, `TSSetExactFinalTime()` 6167cb94ee6SHong Zhang @*/ 617d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsGetIterations(TS ts, int *nonlin, int *lin) 618d71ae5a4SJacob Faibussowitsch { 6197cb94ee6SHong Zhang PetscFunctionBegin; 620cac4c232SBarry Smith PetscUseMethod(ts, "TSSundialsGetIterations_C", (TS, int *, int *), (ts, nonlin, lin)); 6217cb94ee6SHong Zhang PetscFunctionReturn(0); 6227cb94ee6SHong Zhang } 6237cb94ee6SHong Zhang 6247cb94ee6SHong Zhang /*@ 625*bcf0153eSBarry Smith TSSundialsSetType - Sets the method that `TSSUNDIALS` will use for integration. 6267cb94ee6SHong Zhang 627*bcf0153eSBarry Smith Logically Collective on ts 6287cb94ee6SHong Zhang 6298f7d6fe5SPatrick Sanan Input Parameters: 6307cb94ee6SHong Zhang + ts - the time-step context 631*bcf0153eSBarry Smith - type - one of `SUNDIALS_ADAMS` or `SUNDIALS_BDF` 6327cb94ee6SHong Zhang 6337cb94ee6SHong Zhang Level: intermediate 6347cb94ee6SHong Zhang 635*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSSundialsGetIterations()`, `TSSundialsSetMaxl()`, 636db781477SPatrick Sanan `TSSundialsSetLinearTolerance()`, `TSSundialsSetGramSchmidtType()`, `TSSundialsSetTolerance()`, 637db781477SPatrick Sanan `TSSundialsGetIterations()`, `TSSundialsSetType()`, 638db781477SPatrick Sanan `TSSundialsSetLinearTolerance()`, `TSSundialsSetTolerance()`, `TSSundialsGetPC()`, 639db781477SPatrick Sanan `TSSetExactFinalTime()` 6407cb94ee6SHong Zhang @*/ 641d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsSetType(TS ts, TSSundialsLmmType type) 642d71ae5a4SJacob Faibussowitsch { 6437cb94ee6SHong Zhang PetscFunctionBegin; 644cac4c232SBarry Smith PetscTryMethod(ts, "TSSundialsSetType_C", (TS, TSSundialsLmmType), (ts, type)); 6457cb94ee6SHong Zhang PetscFunctionReturn(0); 6467cb94ee6SHong Zhang } 6477cb94ee6SHong Zhang 6487cb94ee6SHong Zhang /*@ 649*bcf0153eSBarry Smith TSSundialsSetMaxord - Sets the maximum order for BDF/Adams method used by `TSSUNDIALS`. 650c4e80e11SFlorian 651*bcf0153eSBarry Smith Logically Collective on ts 652c4e80e11SFlorian 6538f7d6fe5SPatrick Sanan Input Parameters: 654c4e80e11SFlorian + ts - the time-step context 655c4e80e11SFlorian - maxord - maximum order of BDF / Adams method 656c4e80e11SFlorian 657c4e80e11SFlorian Level: advanced 658c4e80e11SFlorian 659*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSSundialsGetIterations()`, `TSSundialsSetType()`, 660db781477SPatrick Sanan `TSSundialsSetLinearTolerance()`, `TSSundialsSetGramSchmidtType()`, `TSSundialsSetTolerance()`, 661db781477SPatrick Sanan `TSSundialsGetIterations()`, `TSSundialsSetType()`, 662db781477SPatrick Sanan `TSSundialsSetLinearTolerance()`, `TSSundialsSetTolerance()`, `TSSundialsGetPC()`, 663db781477SPatrick Sanan `TSSetExactFinalTime()` 664c4e80e11SFlorian @*/ 665d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsSetMaxord(TS ts, PetscInt maxord) 666d71ae5a4SJacob Faibussowitsch { 667c4e80e11SFlorian PetscFunctionBegin; 668c4e80e11SFlorian PetscValidLogicalCollectiveInt(ts, maxord, 2); 669cac4c232SBarry Smith PetscTryMethod(ts, "TSSundialsSetMaxOrd_C", (TS, PetscInt), (ts, maxord)); 670c4e80e11SFlorian PetscFunctionReturn(0); 671c4e80e11SFlorian } 672c4e80e11SFlorian 673c4e80e11SFlorian /*@ 674f61b2b6aSHong Zhang TSSundialsSetMaxl - Sets the dimension of the Krylov space used by 675*bcf0153eSBarry Smith GMRES in the linear solver in `TSSUNDIALS`. `TSSUNDIALS` DOES NOT use restarted GMRES so 676f61b2b6aSHong Zhang this is the maximum number of GMRES steps that will be used. 6777cb94ee6SHong Zhang 678*bcf0153eSBarry Smith Logically Collective on ts 6797cb94ee6SHong Zhang 6808f7d6fe5SPatrick Sanan Input Parameters: 6817cb94ee6SHong Zhang + ts - the time-step context 682f61b2b6aSHong Zhang - maxl - number of direction vectors (the dimension of Krylov subspace). 6837cb94ee6SHong Zhang 6847cb94ee6SHong Zhang Level: advanced 6857cb94ee6SHong Zhang 686*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSSundialsGetIterations()`, `TSSundialsSetType()`, 687db781477SPatrick Sanan `TSSundialsSetLinearTolerance()`, `TSSundialsSetGramSchmidtType()`, `TSSundialsSetTolerance()`, 688db781477SPatrick Sanan `TSSundialsGetIterations()`, `TSSundialsSetType()`, 689db781477SPatrick Sanan `TSSundialsSetLinearTolerance()`, `TSSundialsSetTolerance()`, `TSSundialsGetPC()`, 690db781477SPatrick Sanan `TSSetExactFinalTime()` 6917cb94ee6SHong Zhang @*/ 692d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsSetMaxl(TS ts, PetscInt maxl) 693d71ae5a4SJacob Faibussowitsch { 6947cb94ee6SHong Zhang PetscFunctionBegin; 695f61b2b6aSHong Zhang PetscValidLogicalCollectiveInt(ts, maxl, 2); 696cac4c232SBarry Smith PetscTryMethod(ts, "TSSundialsSetMaxl_C", (TS, PetscInt), (ts, maxl)); 6977cb94ee6SHong Zhang PetscFunctionReturn(0); 6987cb94ee6SHong Zhang } 6997cb94ee6SHong Zhang 7007cb94ee6SHong Zhang /*@ 7017cb94ee6SHong Zhang TSSundialsSetLinearTolerance - Sets the tolerance used to solve the linear 702*bcf0153eSBarry Smith system by `TSSUNDIALS`. 7037cb94ee6SHong Zhang 704*bcf0153eSBarry Smith Logically Collective on ts 7057cb94ee6SHong Zhang 7068f7d6fe5SPatrick Sanan Input Parameters: 7077cb94ee6SHong Zhang + ts - the time-step context 7087cb94ee6SHong Zhang - tol - the factor by which the tolerance on the nonlinear solver is 7097cb94ee6SHong Zhang multiplied to get the tolerance on the linear solver, .05 by default. 7107cb94ee6SHong Zhang 7117cb94ee6SHong Zhang Level: advanced 7127cb94ee6SHong Zhang 713*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSSundialsGetIterations()`, `TSSundialsSetType()`, `TSSundialsSetMaxl()`, 714db781477SPatrick Sanan `TSSundialsSetGramSchmidtType()`, `TSSundialsSetTolerance()`, 715db781477SPatrick Sanan `TSSundialsGetIterations()`, `TSSundialsSetType()`, 716db781477SPatrick Sanan `TSSundialsSetLinearTolerance()`, `TSSundialsSetTolerance()`, `TSSundialsGetPC()`, 717db781477SPatrick Sanan `TSSetExactFinalTime()` 7187cb94ee6SHong Zhang @*/ 719d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsSetLinearTolerance(TS ts, PetscReal tol) 720d71ae5a4SJacob Faibussowitsch { 7217cb94ee6SHong Zhang PetscFunctionBegin; 722c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(ts, tol, 2); 723cac4c232SBarry Smith PetscTryMethod(ts, "TSSundialsSetLinearTolerance_C", (TS, PetscReal), (ts, tol)); 7247cb94ee6SHong Zhang PetscFunctionReturn(0); 7257cb94ee6SHong Zhang } 7267cb94ee6SHong Zhang 7277cb94ee6SHong Zhang /*@ 7287cb94ee6SHong Zhang TSSundialsSetGramSchmidtType - Sets type of orthogonalization used 729*bcf0153eSBarry Smith in GMRES method by `TSSUNDIALS` linear solver. 7307cb94ee6SHong Zhang 731*bcf0153eSBarry Smith Logically Collective on ts 7327cb94ee6SHong Zhang 7338f7d6fe5SPatrick Sanan Input Parameters: 7347cb94ee6SHong Zhang + ts - the time-step context 735*bcf0153eSBarry Smith - type - either `SUNDIALS_MODIFIED_GS` or `SUNDIALS_CLASSICAL_GS` 7367cb94ee6SHong Zhang 7377cb94ee6SHong Zhang Level: advanced 7387cb94ee6SHong Zhang 739*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSSundialsGetIterations()`, `TSSundialsSetType()`, `TSSundialsSetMaxl()`, 740db781477SPatrick Sanan `TSSundialsSetLinearTolerance()`, `TSSundialsSetTolerance()`, 741db781477SPatrick Sanan `TSSundialsGetIterations()`, `TSSundialsSetType()`, 742db781477SPatrick Sanan `TSSundialsSetLinearTolerance()`, `TSSundialsSetTolerance()`, `TSSundialsGetPC()`, 743db781477SPatrick Sanan `TSSetExactFinalTime()` 7447cb94ee6SHong Zhang @*/ 745d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsSetGramSchmidtType(TS ts, TSSundialsGramSchmidtType type) 746d71ae5a4SJacob Faibussowitsch { 7477cb94ee6SHong Zhang PetscFunctionBegin; 748cac4c232SBarry Smith PetscTryMethod(ts, "TSSundialsSetGramSchmidtType_C", (TS, TSSundialsGramSchmidtType), (ts, type)); 7497cb94ee6SHong Zhang PetscFunctionReturn(0); 7507cb94ee6SHong Zhang } 7517cb94ee6SHong Zhang 7527cb94ee6SHong Zhang /*@ 7537cb94ee6SHong Zhang TSSundialsSetTolerance - Sets the absolute and relative tolerance used by 754*bcf0153eSBarry Smith `TSSUNDIALS` for error control. 7557cb94ee6SHong Zhang 756*bcf0153eSBarry Smith Logically Collective on ts 7577cb94ee6SHong Zhang 7588f7d6fe5SPatrick Sanan Input Parameters: 7597cb94ee6SHong Zhang + ts - the time-step context 7607cb94ee6SHong Zhang . aabs - the absolute tolerance 7617cb94ee6SHong Zhang - rel - the relative tolerance 7627cb94ee6SHong Zhang 763*bcf0153eSBarry Smith See the CVODE/SUNDIALS users manual for exact details on these parameters. Essentially 7647cb94ee6SHong Zhang these regulate the size of the error for a SINGLE timestep. 7657cb94ee6SHong Zhang 7667cb94ee6SHong Zhang Level: intermediate 7677cb94ee6SHong Zhang 768*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSSundialsGetIterations()`, `TSSundialsSetType()`, `TSSundialsSetGMRESMaxl()`, 769db781477SPatrick Sanan `TSSundialsSetLinearTolerance()`, `TSSundialsSetGramSchmidtType()`, 770db781477SPatrick Sanan `TSSundialsGetIterations()`, `TSSundialsSetType()`, 771db781477SPatrick Sanan `TSSundialsSetLinearTolerance()`, `TSSundialsSetTolerance()`, `TSSundialsGetPC()`, 772db781477SPatrick Sanan `TSSetExactFinalTime()` 7737cb94ee6SHong Zhang @*/ 774d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsSetTolerance(TS ts, PetscReal aabs, PetscReal rel) 775d71ae5a4SJacob Faibussowitsch { 7767cb94ee6SHong Zhang PetscFunctionBegin; 777cac4c232SBarry Smith PetscTryMethod(ts, "TSSundialsSetTolerance_C", (TS, PetscReal, PetscReal), (ts, aabs, rel)); 7787cb94ee6SHong Zhang PetscFunctionReturn(0); 7797cb94ee6SHong Zhang } 7807cb94ee6SHong Zhang 7817cb94ee6SHong Zhang /*@ 782*bcf0153eSBarry Smith TSSundialsGetPC - Extract the PC context from a time-step context for `TSSUNDIALS`. 7837cb94ee6SHong Zhang 7847cb94ee6SHong Zhang Input Parameter: 7857cb94ee6SHong Zhang . ts - the time-step context 7867cb94ee6SHong Zhang 7877cb94ee6SHong Zhang Output Parameter: 7887cb94ee6SHong Zhang . pc - the preconditioner context 7897cb94ee6SHong Zhang 7907cb94ee6SHong Zhang Level: advanced 7917cb94ee6SHong Zhang 792*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSSundialsGetIterations()`, `TSSundialsSetType()`, `TSSundialsSetMaxl()`, 793db781477SPatrick Sanan `TSSundialsSetLinearTolerance()`, `TSSundialsSetGramSchmidtType()`, `TSSundialsSetTolerance()`, 794db781477SPatrick Sanan `TSSundialsGetIterations()`, `TSSundialsSetType()`, 795db781477SPatrick Sanan `TSSundialsSetLinearTolerance()`, `TSSundialsSetTolerance()` 7967cb94ee6SHong Zhang @*/ 797d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsGetPC(TS ts, PC *pc) 798d71ae5a4SJacob Faibussowitsch { 7997cb94ee6SHong Zhang PetscFunctionBegin; 800cac4c232SBarry Smith PetscUseMethod(ts, "TSSundialsGetPC_C", (TS, PC *), (ts, pc)); 8017cb94ee6SHong Zhang PetscFunctionReturn(0); 8027cb94ee6SHong Zhang } 8037cb94ee6SHong Zhang 804f1cd61daSJed Brown /*@ 805f1cd61daSJed Brown TSSundialsSetMinTimeStep - Smallest time step to be chosen by the adaptive controller. 806f1cd61daSJed Brown 807d8d19677SJose E. Roman Input Parameters: 808f1cd61daSJed Brown + ts - the time-step context 809f1cd61daSJed Brown - mindt - lowest time step if positive, negative to deactivate 810f1cd61daSJed Brown 811fc6b9e64SJed Brown Note: 812*bcf0153eSBarry Smith `TSSUNDIALS` will error if it is not possible to keep the estimated truncation error below 813*bcf0153eSBarry Smith the tolerance set with `TSSundialsSetTolerance()` without going below this step size. 814fc6b9e64SJed Brown 815f1cd61daSJed Brown Level: beginner 816f1cd61daSJed Brown 817*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSSundialsSetType()`, `TSSundialsSetTolerance()`, 818f1cd61daSJed Brown @*/ 819d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsSetMinTimeStep(TS ts, PetscReal mindt) 820d71ae5a4SJacob Faibussowitsch { 821f1cd61daSJed Brown PetscFunctionBegin; 822cac4c232SBarry Smith PetscTryMethod(ts, "TSSundialsSetMinTimeStep_C", (TS, PetscReal), (ts, mindt)); 823f1cd61daSJed Brown PetscFunctionReturn(0); 824f1cd61daSJed Brown } 825f1cd61daSJed Brown 826f1cd61daSJed Brown /*@ 827f1cd61daSJed Brown TSSundialsSetMaxTimeStep - Largest time step to be chosen by the adaptive controller. 828f1cd61daSJed Brown 829d8d19677SJose E. Roman Input Parameters: 830f1cd61daSJed Brown + ts - the time-step context 831f1cd61daSJed Brown - maxdt - lowest time step if positive, negative to deactivate 832f1cd61daSJed Brown 833f1cd61daSJed Brown Level: beginner 834f1cd61daSJed Brown 835*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSSundialsSetType()`, `TSSundialsSetTolerance()`, 836f1cd61daSJed Brown @*/ 837d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsSetMaxTimeStep(TS ts, PetscReal maxdt) 838d71ae5a4SJacob Faibussowitsch { 839f1cd61daSJed Brown PetscFunctionBegin; 840cac4c232SBarry Smith PetscTryMethod(ts, "TSSundialsSetMaxTimeStep_C", (TS, PetscReal), (ts, maxdt)); 841f1cd61daSJed Brown PetscFunctionReturn(0); 842f1cd61daSJed Brown } 843f1cd61daSJed Brown 8442bfc04deSHong Zhang /*@ 845*bcf0153eSBarry Smith TSSundialsMonitorInternalSteps - Monitor `TSSUNDIALS` internal steps (Defaults to false). 8462bfc04deSHong Zhang 847d8d19677SJose E. Roman Input Parameters: 8482bfc04deSHong Zhang + ts - the time-step context 849*bcf0153eSBarry Smith - ft - `PETSC_TRUE` if monitor, else `PETSC_FALSE` 8502bfc04deSHong Zhang 8512bfc04deSHong Zhang Level: beginner 8522bfc04deSHong Zhang 853*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSSundialsGetIterations()`, `TSSundialsSetType()`, `TSSundialsSetMaxl()`, 854*bcf0153eSBarry Smith `TSSundialsSetLinearTolerance()`, `TSSundialsSetGramSchmidtType()`, `TSSundialsSetTolerance()`, 855*bcf0153eSBarry Smith `TSSundialsGetIterations()`, `TSSundialsSetType()`, 856*bcf0153eSBarry Smith `TSSundialsSetLinearTolerance()`, `TSSundialsSetTolerance()`, `TSSundialsGetPC()` 8572bfc04deSHong Zhang @*/ 858d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsMonitorInternalSteps(TS ts, PetscBool ft) 859d71ae5a4SJacob Faibussowitsch { 8602bfc04deSHong Zhang PetscFunctionBegin; 861cac4c232SBarry Smith PetscTryMethod(ts, "TSSundialsMonitorInternalSteps_C", (TS, PetscBool), (ts, ft)); 8622bfc04deSHong Zhang PetscFunctionReturn(0); 8632bfc04deSHong Zhang } 864918687b8SPatrick Sanan 865918687b8SPatrick Sanan /*@ 866*bcf0153eSBarry Smith TSSundialsSetUseDense - Set a flag to use a dense linear solver in `TSSUNDIALS` (serial only) 867918687b8SPatrick Sanan 868918687b8SPatrick Sanan Logically Collective 869918687b8SPatrick Sanan 870918687b8SPatrick Sanan Input Parameters: 871918687b8SPatrick Sanan + ts - the time-step context 872*bcf0153eSBarry Smith - use_dense - `PETSC_TRUE` to use the dense solver 873918687b8SPatrick Sanan 874918687b8SPatrick Sanan Level: advanced 875918687b8SPatrick Sanan 876*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSSUNDIALS` 877918687b8SPatrick Sanan @*/ 878d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSundialsSetUseDense(TS ts, PetscBool use_dense) 879d71ae5a4SJacob Faibussowitsch { 880918687b8SPatrick Sanan PetscFunctionBegin; 881918687b8SPatrick Sanan PetscValidLogicalCollectiveInt(ts, use_dense, 2); 882cac4c232SBarry Smith PetscTryMethod(ts, "TSSundialsSetUseDense_C", (TS, PetscBool), (ts, use_dense)); 883918687b8SPatrick Sanan PetscFunctionReturn(0); 884918687b8SPatrick Sanan } 885918687b8SPatrick Sanan 8867cb94ee6SHong Zhang /* -------------------------------------------------------------------------------------------*/ 8877cb94ee6SHong Zhang /*MC 888*bcf0153eSBarry Smith TSSUNDIALS - ODE solver using a very old version of the LLNL CVODE/SUNDIALS package, version 2.5 (now called SUNDIALS). Requires ./configure --download-sundials 8897cb94ee6SHong Zhang 890*bcf0153eSBarry Smith Options Database Keys: 891897c9f78SHong Zhang + -ts_sundials_type <bdf,adams> - 8927cb94ee6SHong Zhang . -ts_sundials_gramschmidt_type <modified, classical> - type of orthogonalization inside GMRES 8937cb94ee6SHong Zhang . -ts_sundials_atol <tol> - Absolute tolerance for convergence 8947cb94ee6SHong Zhang . -ts_sundials_rtol <tol> - Relative tolerance for convergence 895897c9f78SHong Zhang . -ts_sundials_linear_tolerance <tol> - 896f61b2b6aSHong Zhang . -ts_sundials_maxl <maxl> - Max dimension of the Krylov subspace 897918687b8SPatrick Sanan . -ts_sundials_monitor_steps - Monitor SUNDIALS internal steps 898918687b8SPatrick Sanan - -ts_sundials_use_dense - Use a dense linear solver within CVODE (serial only) 89916016685SHong Zhang 9007cb94ee6SHong Zhang Level: beginner 9017cb94ee6SHong Zhang 902*bcf0153eSBarry Smith Note: 903*bcf0153eSBarry Smith This uses its own nonlinear solver and Krylov method so PETSc `SNES` and `KSP` options do not apply, 904*bcf0153eSBarry Smith only PETSc `PC` options. 9057cb94ee6SHong Zhang 906*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSCreate()`, `TS`, `TSSetType()`, `TSSundialsSetType()`, `TSSundialsSetMaxl()`, `TSSundialsSetLinearTolerance()`, `TSType`, 907*bcf0153eSBarry Smith `TSSundialsSetGramSchmidtType()`, `TSSundialsSetTolerance()`, `TSSundialsGetPC()`, `TSSundialsGetIterations()`, `TSSetExactFinalTime()` 9087cb94ee6SHong Zhang M*/ 909d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode TSCreate_Sundials(TS ts) 910d71ae5a4SJacob Faibussowitsch { 9117cb94ee6SHong Zhang TS_Sundials *cvode; 91242528757SHong Zhang PC pc; 9137cb94ee6SHong Zhang 9147cb94ee6SHong Zhang PetscFunctionBegin; 915277b19d0SLisandro Dalcin ts->ops->reset = TSReset_Sundials; 91628adb3f7SHong Zhang ts->ops->destroy = TSDestroy_Sundials; 91728adb3f7SHong Zhang ts->ops->view = TSView_Sundials; 918214bc6a2SJed Brown ts->ops->setup = TSSetUp_Sundials; 919b4eba00bSSean Farley ts->ops->step = TSStep_Sundials; 920b4eba00bSSean Farley ts->ops->interpolate = TSInterpolate_Sundials; 921214bc6a2SJed Brown ts->ops->setfromoptions = TSSetFromOptions_Sundials; 9222ffb9264SLisandro Dalcin ts->default_adapt_type = TSADAPTNONE; 9237cb94ee6SHong Zhang 9244dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&cvode)); 925bbd56ea5SKarl Rupp 926efd4aadfSBarry Smith ts->usessnes = PETSC_TRUE; 927efd4aadfSBarry Smith 9287cb94ee6SHong Zhang ts->data = (void *)cvode; 9296fadb2cdSHong Zhang cvode->cvode_type = SUNDIALS_BDF; 9306fadb2cdSHong Zhang cvode->gtype = SUNDIALS_CLASSICAL_GS; 931f61b2b6aSHong Zhang cvode->maxl = 5; 932c4e80e11SFlorian cvode->maxord = PETSC_DEFAULT; 9337cb94ee6SHong Zhang cvode->linear_tol = .05; 934b4eba00bSSean Farley cvode->monitorstep = PETSC_TRUE; 935918687b8SPatrick Sanan cvode->use_dense = PETSC_FALSE; 9367cb94ee6SHong Zhang 9379566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_dup(PetscObjectComm((PetscObject)ts), &(cvode->comm_sundials))); 938f1cd61daSJed Brown 939f1cd61daSJed Brown cvode->mindt = -1.; 940f1cd61daSJed Brown cvode->maxdt = -1.; 941f1cd61daSJed Brown 942*bcf0153eSBarry Smith /* set tolerance for SUNDIALS */ 9437cb94ee6SHong Zhang cvode->reltol = 1e-6; 9442c823083SHong Zhang cvode->abstol = 1e-6; 9457cb94ee6SHong Zhang 94642528757SHong Zhang /* set PCNONE as default pctype */ 9479566063dSJacob Faibussowitsch PetscCall(TSSundialsGetPC_Sundials(ts, &pc)); 9489566063dSJacob Faibussowitsch PetscCall(PCSetType(pc, PCNONE)); 94942528757SHong Zhang 9509566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsSetType_C", TSSundialsSetType_Sundials)); 9519566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsSetMaxl_C", TSSundialsSetMaxl_Sundials)); 9529566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsSetLinearTolerance_C", TSSundialsSetLinearTolerance_Sundials)); 9539566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsSetGramSchmidtType_C", TSSundialsSetGramSchmidtType_Sundials)); 9549566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsSetTolerance_C", TSSundialsSetTolerance_Sundials)); 9559566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsSetMinTimeStep_C", TSSundialsSetMinTimeStep_Sundials)); 9569566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsSetMaxTimeStep_C", TSSundialsSetMaxTimeStep_Sundials)); 9579566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsGetPC_C", TSSundialsGetPC_Sundials)); 9589566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsGetIterations_C", TSSundialsGetIterations_Sundials)); 9599566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsMonitorInternalSteps_C", TSSundialsMonitorInternalSteps_Sundials)); 9609566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)ts, "TSSundialsSetUseDense_C", TSSundialsSetUseDense_Sundials)); 9617cb94ee6SHong Zhang PetscFunctionReturn(0); 9627cb94ee6SHong Zhang } 963