1 2 #include <petsc-private/tsimpl.h> /*I "petscts.h" I*/ 3 #include <petscdmshell.h> 4 #include <petscdmda.h> 5 #include <petscviewer.h> 6 #include <petscdraw.h> 7 8 /* Logging support */ 9 PetscClassId TS_CLASSID, DMTS_CLASSID; 10 PetscLogEvent TS_Step, TS_PseudoComputeTimeStep, TS_FunctionEval, TS_JacobianEval; 11 12 const char *const TSExactFinalTimeOptions[] = {"STEPOVER","INTERPOLATE","MATCHSTEP","TSExactFinalTimeOption","TS_EXACTFINALTIME_",0}; 13 14 #undef __FUNCT__ 15 #define __FUNCT__ "TSSetTypeFromOptions" 16 /* 17 TSSetTypeFromOptions - Sets the type of ts from user options. 18 19 Collective on TS 20 21 Input Parameter: 22 . ts - The ts 23 24 Level: intermediate 25 26 .keywords: TS, set, options, database, type 27 .seealso: TSSetFromOptions(), TSSetType() 28 */ 29 static PetscErrorCode TSSetTypeFromOptions(TS ts) 30 { 31 PetscBool opt; 32 const char *defaultType; 33 char typeName[256]; 34 PetscErrorCode ierr; 35 36 PetscFunctionBegin; 37 if (((PetscObject)ts)->type_name) defaultType = ((PetscObject)ts)->type_name; 38 else defaultType = TSEULER; 39 40 if (!TSRegisterAllCalled) {ierr = TSRegisterAll();CHKERRQ(ierr);} 41 ierr = PetscOptionsList("-ts_type", "TS method"," TSSetType", TSList, defaultType, typeName, 256, &opt);CHKERRQ(ierr); 42 if (opt) { 43 ierr = TSSetType(ts, typeName);CHKERRQ(ierr); 44 } else { 45 ierr = TSSetType(ts, defaultType);CHKERRQ(ierr); 46 } 47 PetscFunctionReturn(0); 48 } 49 50 struct _n_TSMonitorDrawCtx { 51 PetscViewer viewer; 52 PetscDrawAxis axis; 53 Vec initialsolution; 54 PetscBool showinitial; 55 PetscInt howoften; /* when > 0 uses step % howoften, when negative only final solution plotted */ 56 PetscBool showtimestepandtime; 57 int color; 58 }; 59 60 #undef __FUNCT__ 61 #define __FUNCT__ "TSSetFromOptions" 62 /*@ 63 TSSetFromOptions - Sets various TS parameters from user options. 64 65 Collective on TS 66 67 Input Parameter: 68 . ts - the TS context obtained from TSCreate() 69 70 Options Database Keys: 71 + -ts_type <type> - TSEULER, TSBEULER, TSSUNDIALS, TSPSEUDO, TSCN, TSRK, TSTHETA, TSGL, TSSSP 72 . -ts_max_steps maxsteps - maximum number of time-steps to take 73 . -ts_final_time time - maximum time to compute to 74 . -ts_dt dt - initial time step 75 . -ts_monitor - print information at each timestep 76 . -ts_monitor_lg_timestep - Monitor timestep size graphically 77 . -ts_monitor_lg_solution - Monitor solution graphically 78 . -ts_monitor_lg_error - Monitor error graphically 79 . -ts_monitor_lg_snes_iterations - Monitor number nonlinear iterations for each timestep graphically 80 . -ts_monitor_lg_ksp_iterations - Monitor number nonlinear iterations for each timestep graphically 81 . -ts_monitor_sp_eig - Monitor eigenvalues of linearized operator graphically 82 . -ts_monitor_draw_solution - Monitor solution graphically 83 . -ts_monitor_draw_solution_phase - Monitor solution graphically with phase diagram 84 . -ts_monitor_draw_error - Monitor error graphically 85 . -ts_monitor_solution_binary <filename> - Save each solution to a binary file 86 - -ts_monitor_solution_vtk <filename.vts> - Save each time step to a binary file, use filename-%%03D.vts 87 88 Developer Note: We should unify all the -ts_monitor options in the way that -xxx_view has been unified 89 90 Level: beginner 91 92 .keywords: TS, timestep, set, options, database 93 94 .seealso: TSGetType() 95 @*/ 96 PetscErrorCode TSSetFromOptions(TS ts) 97 { 98 PetscBool opt,flg; 99 PetscErrorCode ierr; 100 PetscViewer monviewer; 101 char monfilename[PETSC_MAX_PATH_LEN]; 102 SNES snes; 103 TSAdapt adapt; 104 PetscReal time_step; 105 TSExactFinalTimeOption eftopt; 106 char dir[16]; 107 108 PetscFunctionBegin; 109 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 110 ierr = PetscObjectOptionsBegin((PetscObject)ts);CHKERRQ(ierr); 111 /* Handle TS type options */ 112 ierr = TSSetTypeFromOptions(ts);CHKERRQ(ierr); 113 114 /* Handle generic TS options */ 115 ierr = PetscOptionsInt("-ts_max_steps","Maximum number of time steps","TSSetDuration",ts->max_steps,&ts->max_steps,NULL);CHKERRQ(ierr); 116 ierr = PetscOptionsReal("-ts_final_time","Time to run to","TSSetDuration",ts->max_time,&ts->max_time,NULL);CHKERRQ(ierr); 117 ierr = PetscOptionsReal("-ts_init_time","Initial time","TSSetTime",ts->ptime,&ts->ptime,NULL);CHKERRQ(ierr); 118 ierr = PetscOptionsReal("-ts_dt","Initial time step","TSSetTimeStep",ts->time_step,&time_step,&flg);CHKERRQ(ierr); 119 if (flg) { 120 ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr); 121 } 122 ierr = PetscOptionsEnum("-ts_exact_final_time","Option for handling of final time step","TSSetExactFinalTime",TSExactFinalTimeOptions,(PetscEnum)ts->exact_final_time,(PetscEnum*)&eftopt,&flg);CHKERRQ(ierr); 123 if (flg) {ierr = TSSetExactFinalTime(ts,eftopt);CHKERRQ(ierr);} 124 ierr = PetscOptionsInt("-ts_max_snes_failures","Maximum number of nonlinear solve failures","TSSetMaxSNESFailures",ts->max_snes_failures,&ts->max_snes_failures,NULL);CHKERRQ(ierr); 125 ierr = PetscOptionsInt("-ts_max_reject","Maximum number of step rejections before step fails","TSSetMaxStepRejections",ts->max_reject,&ts->max_reject,NULL);CHKERRQ(ierr); 126 ierr = PetscOptionsBool("-ts_error_if_step_fails","Error if no step succeeds","TSSetErrorIfStepFails",ts->errorifstepfailed,&ts->errorifstepfailed,NULL);CHKERRQ(ierr); 127 ierr = PetscOptionsReal("-ts_rtol","Relative tolerance for local truncation error","TSSetTolerances",ts->rtol,&ts->rtol,NULL);CHKERRQ(ierr); 128 ierr = PetscOptionsReal("-ts_atol","Absolute tolerance for local truncation error","TSSetTolerances",ts->atol,&ts->atol,NULL);CHKERRQ(ierr); 129 130 #if defined(PETSC_HAVE_SAWS) 131 { 132 PetscBool set; 133 flg = PETSC_FALSE; 134 ierr = PetscOptionsBool("-ts_saws_block","Block for SAWs memory snooper at end of TSSolve","PetscObjectSAWsBlock",((PetscObject)ts)->amspublishblock,&flg,&set);CHKERRQ(ierr); 135 if (set) { 136 ierr = PetscObjectSAWsSetBlock((PetscObject)ts,flg);CHKERRQ(ierr); 137 } 138 } 139 #endif 140 141 /* Monitor options */ 142 ierr = PetscOptionsString("-ts_monitor","Monitor timestep size","TSMonitorDefault","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 143 if (flg) { 144 ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ts),monfilename,&monviewer);CHKERRQ(ierr); 145 ierr = TSMonitorSet(ts,TSMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 146 } 147 ierr = PetscOptionsString("-ts_monitor_python","Use Python function","TSMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 148 if (flg) {ierr = PetscPythonMonitorSet((PetscObject)ts,monfilename);CHKERRQ(ierr);} 149 150 ierr = PetscOptionsName("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",&opt);CHKERRQ(ierr); 151 if (opt) { 152 TSMonitorLGCtx ctx; 153 PetscInt howoften = 1; 154 155 ierr = PetscOptionsInt("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",howoften,&howoften,NULL);CHKERRQ(ierr); 156 ierr = TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 157 ierr = TSMonitorSet(ts,TSMonitorLGTimeStep,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 158 } 159 ierr = PetscOptionsName("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",&opt);CHKERRQ(ierr); 160 if (opt) { 161 TSMonitorLGCtx ctx; 162 PetscInt howoften = 1; 163 164 ierr = PetscOptionsInt("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",howoften,&howoften,NULL);CHKERRQ(ierr); 165 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr); 166 ierr = TSMonitorSet(ts,TSMonitorLGSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 167 } 168 ierr = PetscOptionsName("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",&opt);CHKERRQ(ierr); 169 if (opt) { 170 TSMonitorLGCtx ctx; 171 PetscInt howoften = 1; 172 173 ierr = PetscOptionsInt("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",howoften,&howoften,NULL);CHKERRQ(ierr); 174 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr); 175 ierr = TSMonitorSet(ts,TSMonitorLGError,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 176 } 177 ierr = PetscOptionsName("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",&opt);CHKERRQ(ierr); 178 if (opt) { 179 TSMonitorLGCtx ctx; 180 PetscInt howoften = 1; 181 182 ierr = PetscOptionsInt("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",howoften,&howoften,NULL);CHKERRQ(ierr); 183 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 184 ierr = TSMonitorSet(ts,TSMonitorLGSNESIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 185 } 186 ierr = PetscOptionsName("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",&opt);CHKERRQ(ierr); 187 if (opt) { 188 TSMonitorLGCtx ctx; 189 PetscInt howoften = 1; 190 191 ierr = PetscOptionsInt("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",howoften,&howoften,NULL);CHKERRQ(ierr); 192 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 193 ierr = TSMonitorSet(ts,TSMonitorLGKSPIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 194 } 195 ierr = PetscOptionsName("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",&opt);CHKERRQ(ierr); 196 if (opt) { 197 TSMonitorSPEigCtx ctx; 198 PetscInt howoften = 1; 199 200 ierr = PetscOptionsInt("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",howoften,&howoften,NULL);CHKERRQ(ierr); 201 ierr = TSMonitorSPEigCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr); 202 ierr = TSMonitorSet(ts,TSMonitorSPEig,ctx,(PetscErrorCode (*)(void**))TSMonitorSPEigCtxDestroy);CHKERRQ(ierr); 203 } 204 opt = PETSC_FALSE; 205 ierr = PetscOptionsName("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",&opt);CHKERRQ(ierr); 206 if (opt) { 207 TSMonitorDrawCtx ctx; 208 PetscInt howoften = 1; 209 210 ierr = PetscOptionsInt("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",howoften,&howoften,NULL);CHKERRQ(ierr); 211 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr); 212 ierr = TSMonitorSet(ts,TSMonitorDrawSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 213 } 214 opt = PETSC_FALSE; 215 ierr = PetscOptionsName("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",&opt);CHKERRQ(ierr); 216 if (opt) { 217 TSMonitorDrawCtx ctx; 218 PetscReal bounds[4]; 219 PetscInt n = 4; 220 PetscDraw draw; 221 222 ierr = PetscOptionsRealArray("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",bounds,&n,NULL);CHKERRQ(ierr); 223 if (n != 4) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Must provide bounding box of phase field"); 224 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,1,&ctx);CHKERRQ(ierr); 225 ierr = PetscViewerDrawGetDraw(ctx->viewer,0,&draw);CHKERRQ(ierr); 226 ierr = PetscDrawClear(draw);CHKERRQ(ierr); 227 ierr = PetscDrawAxisCreate(draw,&ctx->axis);CHKERRQ(ierr); 228 ierr = PetscDrawAxisSetLimits(ctx->axis,bounds[0],bounds[2],bounds[1],bounds[3]);CHKERRQ(ierr); 229 ierr = PetscDrawAxisSetLabels(ctx->axis,"Phase Diagram","Variable 1","Variable 2");CHKERRQ(ierr); 230 ierr = PetscDrawAxisDraw(ctx->axis);CHKERRQ(ierr); 231 /* ierr = PetscDrawSetCoordinates(draw,bounds[0],bounds[1],bounds[2],bounds[3]);CHKERRQ(ierr); */ 232 ierr = TSMonitorSet(ts,TSMonitorDrawSolutionPhase,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 233 } 234 opt = PETSC_FALSE; 235 ierr = PetscOptionsName("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",&opt);CHKERRQ(ierr); 236 if (opt) { 237 TSMonitorDrawCtx ctx; 238 PetscInt howoften = 1; 239 240 ierr = PetscOptionsInt("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",howoften,&howoften,NULL);CHKERRQ(ierr); 241 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr); 242 ierr = TSMonitorSet(ts,TSMonitorDrawError,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 243 } 244 opt = PETSC_FALSE; 245 ierr = PetscOptionsString("-ts_monitor_solution_binary","Save each solution to a binary file","TSMonitorSolutionBinary",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 246 if (flg) { 247 PetscViewer ctx; 248 if (monfilename[0]) { 249 ierr = PetscViewerBinaryOpen(PetscObjectComm((PetscObject)ts),monfilename,FILE_MODE_WRITE,&ctx);CHKERRQ(ierr); 250 ierr = TSMonitorSet(ts,TSMonitorSolutionBinary,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 251 } else { 252 ctx = PETSC_VIEWER_BINARY_(PetscObjectComm((PetscObject)ts)); 253 ierr = TSMonitorSet(ts,TSMonitorSolutionBinary,ctx,(PetscErrorCode (*)(void**))NULL);CHKERRQ(ierr); 254 } 255 } 256 opt = PETSC_FALSE; 257 ierr = PetscOptionsString("-ts_monitor_solution_vtk","Save each time step to a binary file, use filename-%%03D.vts","TSMonitorSolutionVTK",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 258 if (flg) { 259 const char *ptr,*ptr2; 260 char *filetemplate; 261 if (!monfilename[0]) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts"); 262 /* Do some cursory validation of the input. */ 263 ierr = PetscStrstr(monfilename,"%",(char**)&ptr);CHKERRQ(ierr); 264 if (!ptr) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts"); 265 for (ptr++; ptr && *ptr; ptr++) { 266 ierr = PetscStrchr("DdiouxX",*ptr,(char**)&ptr2);CHKERRQ(ierr); 267 if (!ptr2 && (*ptr < '0' || '9' < *ptr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Invalid file template argument to -ts_monitor_solution_vtk, should look like filename-%%03D.vts"); 268 if (ptr2) break; 269 } 270 ierr = PetscStrallocpy(monfilename,&filetemplate);CHKERRQ(ierr); 271 ierr = TSMonitorSet(ts,TSMonitorSolutionVTK,filetemplate,(PetscErrorCode (*)(void**))TSMonitorSolutionVTKDestroy);CHKERRQ(ierr); 272 } 273 274 ierr = PetscOptionsString("-ts_monitor_dmda_ray","Display a ray of the solution","None","y=0",dir,16,&flg);CHKERRQ(ierr); 275 if (flg) { 276 TSMonitorDMDARayCtx *rayctx; 277 int ray = 0; 278 DMDADirection ddir; 279 DM da; 280 PetscMPIInt rank; 281 282 if (dir[1] != '=') SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir); 283 if (dir[0] == 'x') ddir = DMDA_X; 284 else if (dir[0] == 'y') ddir = DMDA_Y; 285 else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir); 286 sscanf(dir+2,"%d",&ray); 287 288 ierr = PetscInfo2(((PetscObject)ts),"Displaying DMDA ray %c = %D\n",dir[0],ray);CHKERRQ(ierr); 289 ierr = PetscNew(TSMonitorDMDARayCtx,&rayctx);CHKERRQ(ierr); 290 ierr = TSGetDM(ts,&da);CHKERRQ(ierr); 291 ierr = DMDAGetRay(da,ddir,ray,&rayctx->ray,&rayctx->scatter);CHKERRQ(ierr); 292 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)ts),&rank);CHKERRQ(ierr); 293 if (!rank) { 294 ierr = PetscViewerDrawOpen(PETSC_COMM_SELF,0,0,0,0,600,300,&rayctx->viewer);CHKERRQ(ierr); 295 } 296 ierr = TSMonitorSet(ts,TSMonitorDMDARay,rayctx,TSMonitorDMDARayDestroy);CHKERRQ(ierr); 297 } 298 299 /* 300 This code is all wrong. One is creating objects inside the TSSetFromOptions() so if run with the options gui 301 will bleed memory. Also one is using a PetscOptionsBegin() inside a PetscOptionsBegin() 302 */ 303 ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr); 304 ierr = TSAdaptSetFromOptions(adapt);CHKERRQ(ierr); 305 306 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 307 if (ts->problem_type == TS_LINEAR) {ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);} 308 309 /* Handle specific TS options */ 310 if (ts->ops->setfromoptions) { 311 ierr = (*ts->ops->setfromoptions)(ts);CHKERRQ(ierr); 312 } 313 314 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 315 ierr = PetscObjectProcessOptionsHandlers((PetscObject)ts);CHKERRQ(ierr); 316 ierr = PetscOptionsEnd();CHKERRQ(ierr); 317 PetscFunctionReturn(0); 318 } 319 320 #undef __FUNCT__ 321 #undef __FUNCT__ 322 #define __FUNCT__ "TSComputeRHSJacobian" 323 /*@ 324 TSComputeRHSJacobian - Computes the Jacobian matrix that has been 325 set with TSSetRHSJacobian(). 326 327 Collective on TS and Vec 328 329 Input Parameters: 330 + ts - the TS context 331 . t - current timestep 332 - U - input vector 333 334 Output Parameters: 335 + A - Jacobian matrix 336 . B - optional preconditioning matrix 337 - flag - flag indicating matrix structure 338 339 Notes: 340 Most users should not need to explicitly call this routine, as it 341 is used internally within the nonlinear solvers. 342 343 See KSPSetOperators() for important information about setting the 344 flag parameter. 345 346 Level: developer 347 348 .keywords: SNES, compute, Jacobian, matrix 349 350 .seealso: TSSetRHSJacobian(), KSPSetOperators() 351 @*/ 352 PetscErrorCode TSComputeRHSJacobian(TS ts,PetscReal t,Vec U,Mat *A,Mat *B,MatStructure *flg) 353 { 354 PetscErrorCode ierr; 355 PetscInt Ustate; 356 DM dm; 357 DMTS tsdm; 358 TSRHSJacobian rhsjacobianfunc; 359 void *ctx; 360 TSIJacobian ijacobianfunc; 361 362 PetscFunctionBegin; 363 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 364 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 365 PetscCheckSameComm(ts,1,U,3); 366 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 367 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 368 ierr = DMTSGetRHSJacobian(dm,&rhsjacobianfunc,&ctx);CHKERRQ(ierr); 369 ierr = DMTSGetIJacobian(dm,&ijacobianfunc,NULL);CHKERRQ(ierr); 370 ierr = PetscObjectStateQuery((PetscObject)U,&Ustate);CHKERRQ(ierr); 371 if (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.X == U && ts->rhsjacobian.Xstate == Ustate))) { 372 *flg = ts->rhsjacobian.mstructure; 373 PetscFunctionReturn(0); 374 } 375 376 if (!rhsjacobianfunc && !ijacobianfunc) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()"); 377 378 if (ts->rhsjacobian.reuse) { 379 ierr = MatShift(*A,-ts->rhsjacobian.shift);CHKERRQ(ierr); 380 ierr = MatScale(*A,1./ts->rhsjacobian.scale);CHKERRQ(ierr); 381 if (*A != *B) { 382 ierr = MatShift(*B,-ts->rhsjacobian.shift);CHKERRQ(ierr); 383 ierr = MatScale(*B,1./ts->rhsjacobian.scale);CHKERRQ(ierr); 384 } 385 ts->rhsjacobian.shift = 0; 386 ts->rhsjacobian.scale = 1.; 387 } 388 389 if (rhsjacobianfunc) { 390 ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,*A,*B);CHKERRQ(ierr); 391 *flg = DIFFERENT_NONZERO_PATTERN; 392 PetscStackPush("TS user Jacobian function"); 393 ierr = (*rhsjacobianfunc)(ts,t,U,A,B,flg,ctx);CHKERRQ(ierr); 394 PetscStackPop; 395 ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,*A,*B);CHKERRQ(ierr); 396 /* make sure user returned a correct Jacobian and preconditioner */ 397 PetscValidHeaderSpecific(*A,MAT_CLASSID,4); 398 PetscValidHeaderSpecific(*B,MAT_CLASSID,5); 399 } else { 400 ierr = MatZeroEntries(*A);CHKERRQ(ierr); 401 if (*A != *B) {ierr = MatZeroEntries(*B);CHKERRQ(ierr);} 402 *flg = SAME_NONZERO_PATTERN; 403 } 404 ts->rhsjacobian.time = t; 405 ts->rhsjacobian.X = U; 406 ierr = PetscObjectStateQuery((PetscObject)U,&ts->rhsjacobian.Xstate);CHKERRQ(ierr); 407 ts->rhsjacobian.mstructure = *flg; 408 PetscFunctionReturn(0); 409 } 410 411 #undef __FUNCT__ 412 #define __FUNCT__ "TSComputeRHSFunction" 413 /*@ 414 TSComputeRHSFunction - Evaluates the right-hand-side function. 415 416 Collective on TS and Vec 417 418 Input Parameters: 419 + ts - the TS context 420 . t - current time 421 - U - state vector 422 423 Output Parameter: 424 . y - right hand side 425 426 Note: 427 Most users should not need to explicitly call this routine, as it 428 is used internally within the nonlinear solvers. 429 430 Level: developer 431 432 .keywords: TS, compute 433 434 .seealso: TSSetRHSFunction(), TSComputeIFunction() 435 @*/ 436 PetscErrorCode TSComputeRHSFunction(TS ts,PetscReal t,Vec U,Vec y) 437 { 438 PetscErrorCode ierr; 439 TSRHSFunction rhsfunction; 440 TSIFunction ifunction; 441 void *ctx; 442 DM dm; 443 444 PetscFunctionBegin; 445 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 446 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 447 PetscValidHeaderSpecific(y,VEC_CLASSID,4); 448 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 449 ierr = DMTSGetRHSFunction(dm,&rhsfunction,&ctx);CHKERRQ(ierr); 450 ierr = DMTSGetIFunction(dm,&ifunction,NULL);CHKERRQ(ierr); 451 452 if (!rhsfunction && !ifunction) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 453 454 ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr); 455 if (rhsfunction) { 456 PetscStackPush("TS user right-hand-side function"); 457 ierr = (*rhsfunction)(ts,t,U,y,ctx);CHKERRQ(ierr); 458 PetscStackPop; 459 } else { 460 ierr = VecZeroEntries(y);CHKERRQ(ierr); 461 } 462 463 ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr); 464 PetscFunctionReturn(0); 465 } 466 467 #undef __FUNCT__ 468 #define __FUNCT__ "TSComputeSolutionFunction" 469 /*@ 470 TSComputeSolutionFunction - Evaluates the solution function. 471 472 Collective on TS and Vec 473 474 Input Parameters: 475 + ts - the TS context 476 - t - current time 477 478 Output Parameter: 479 . U - the solution 480 481 Note: 482 Most users should not need to explicitly call this routine, as it 483 is used internally within the nonlinear solvers. 484 485 Level: developer 486 487 .keywords: TS, compute 488 489 .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction() 490 @*/ 491 PetscErrorCode TSComputeSolutionFunction(TS ts,PetscReal t,Vec U) 492 { 493 PetscErrorCode ierr; 494 TSSolutionFunction solutionfunction; 495 void *ctx; 496 DM dm; 497 498 PetscFunctionBegin; 499 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 500 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 501 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 502 ierr = DMTSGetSolutionFunction(dm,&solutionfunction,&ctx);CHKERRQ(ierr); 503 504 if (solutionfunction) { 505 PetscStackPush("TS user solution function"); 506 ierr = (*solutionfunction)(ts,t,U,ctx);CHKERRQ(ierr); 507 PetscStackPop; 508 } 509 PetscFunctionReturn(0); 510 } 511 #undef __FUNCT__ 512 #define __FUNCT__ "TSComputeForcingFunction" 513 /*@ 514 TSComputeForcingFunction - Evaluates the forcing function. 515 516 Collective on TS and Vec 517 518 Input Parameters: 519 + ts - the TS context 520 - t - current time 521 522 Output Parameter: 523 . U - the function value 524 525 Note: 526 Most users should not need to explicitly call this routine, as it 527 is used internally within the nonlinear solvers. 528 529 Level: developer 530 531 .keywords: TS, compute 532 533 .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction() 534 @*/ 535 PetscErrorCode TSComputeForcingFunction(TS ts,PetscReal t,Vec U) 536 { 537 PetscErrorCode ierr, (*forcing)(TS,PetscReal,Vec,void*); 538 void *ctx; 539 DM dm; 540 541 PetscFunctionBegin; 542 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 543 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 544 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 545 ierr = DMTSGetForcingFunction(dm,&forcing,&ctx);CHKERRQ(ierr); 546 547 if (forcing) { 548 PetscStackPush("TS user forcing function"); 549 ierr = (*forcing)(ts,t,U,ctx);CHKERRQ(ierr); 550 PetscStackPop; 551 } 552 PetscFunctionReturn(0); 553 } 554 555 #undef __FUNCT__ 556 #define __FUNCT__ "TSGetRHSVec_Private" 557 static PetscErrorCode TSGetRHSVec_Private(TS ts,Vec *Frhs) 558 { 559 Vec F; 560 PetscErrorCode ierr; 561 562 PetscFunctionBegin; 563 *Frhs = NULL; 564 ierr = TSGetIFunction(ts,&F,NULL,NULL);CHKERRQ(ierr); 565 if (!ts->Frhs) { 566 ierr = VecDuplicate(F,&ts->Frhs);CHKERRQ(ierr); 567 } 568 *Frhs = ts->Frhs; 569 PetscFunctionReturn(0); 570 } 571 572 #undef __FUNCT__ 573 #define __FUNCT__ "TSGetRHSMats_Private" 574 static PetscErrorCode TSGetRHSMats_Private(TS ts,Mat *Arhs,Mat *Brhs) 575 { 576 Mat A,B; 577 PetscErrorCode ierr; 578 579 PetscFunctionBegin; 580 ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr); 581 if (Arhs) { 582 if (!ts->Arhs) { 583 ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&ts->Arhs);CHKERRQ(ierr); 584 } 585 *Arhs = ts->Arhs; 586 } 587 if (Brhs) { 588 if (!ts->Brhs) { 589 ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&ts->Brhs);CHKERRQ(ierr); 590 } 591 *Brhs = ts->Brhs; 592 } 593 PetscFunctionReturn(0); 594 } 595 596 #undef __FUNCT__ 597 #define __FUNCT__ "TSComputeIFunction" 598 /*@ 599 TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,U,Udot)=0 600 601 Collective on TS and Vec 602 603 Input Parameters: 604 + ts - the TS context 605 . t - current time 606 . U - state vector 607 . Udot - time derivative of state vector 608 - imex - flag indicates if the method is IMEX so that the RHSFunction should be kept separate 609 610 Output Parameter: 611 . Y - right hand side 612 613 Note: 614 Most users should not need to explicitly call this routine, as it 615 is used internally within the nonlinear solvers. 616 617 If the user did did not write their equations in implicit form, this 618 function recasts them in implicit form. 619 620 Level: developer 621 622 .keywords: TS, compute 623 624 .seealso: TSSetIFunction(), TSComputeRHSFunction() 625 @*/ 626 PetscErrorCode TSComputeIFunction(TS ts,PetscReal t,Vec U,Vec Udot,Vec Y,PetscBool imex) 627 { 628 PetscErrorCode ierr; 629 TSIFunction ifunction; 630 TSRHSFunction rhsfunction; 631 void *ctx; 632 DM dm; 633 634 PetscFunctionBegin; 635 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 636 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 637 PetscValidHeaderSpecific(Udot,VEC_CLASSID,4); 638 PetscValidHeaderSpecific(Y,VEC_CLASSID,5); 639 640 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 641 ierr = DMTSGetIFunction(dm,&ifunction,&ctx);CHKERRQ(ierr); 642 ierr = DMTSGetRHSFunction(dm,&rhsfunction,NULL);CHKERRQ(ierr); 643 644 if (!rhsfunction && !ifunction) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 645 646 ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr); 647 if (ifunction) { 648 PetscStackPush("TS user implicit function"); 649 ierr = (*ifunction)(ts,t,U,Udot,Y,ctx);CHKERRQ(ierr); 650 PetscStackPop; 651 } 652 if (imex) { 653 if (!ifunction) { 654 ierr = VecCopy(Udot,Y);CHKERRQ(ierr); 655 } 656 } else if (rhsfunction) { 657 if (ifunction) { 658 Vec Frhs; 659 ierr = TSGetRHSVec_Private(ts,&Frhs);CHKERRQ(ierr); 660 ierr = TSComputeRHSFunction(ts,t,U,Frhs);CHKERRQ(ierr); 661 ierr = VecAXPY(Y,-1,Frhs);CHKERRQ(ierr); 662 } else { 663 ierr = TSComputeRHSFunction(ts,t,U,Y);CHKERRQ(ierr); 664 ierr = VecAYPX(Y,-1,Udot);CHKERRQ(ierr); 665 } 666 } 667 ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr); 668 PetscFunctionReturn(0); 669 } 670 671 #undef __FUNCT__ 672 #define __FUNCT__ "TSComputeIJacobian" 673 /*@ 674 TSComputeIJacobian - Evaluates the Jacobian of the DAE 675 676 Collective on TS and Vec 677 678 Input 679 Input Parameters: 680 + ts - the TS context 681 . t - current timestep 682 . U - state vector 683 . Udot - time derivative of state vector 684 . shift - shift to apply, see note below 685 - imex - flag indicates if the method is IMEX so that the RHSJacobian should be kept separate 686 687 Output Parameters: 688 + A - Jacobian matrix 689 . B - optional preconditioning matrix 690 - flag - flag indicating matrix structure 691 692 Notes: 693 If F(t,U,Udot)=0 is the DAE, the required Jacobian is 694 695 dF/dU + shift*dF/dUdot 696 697 Most users should not need to explicitly call this routine, as it 698 is used internally within the nonlinear solvers. 699 700 Level: developer 701 702 .keywords: TS, compute, Jacobian, matrix 703 704 .seealso: TSSetIJacobian() 705 @*/ 706 PetscErrorCode TSComputeIJacobian(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,PetscBool imex) 707 { 708 PetscErrorCode ierr; 709 TSIJacobian ijacobian; 710 TSRHSJacobian rhsjacobian; 711 DM dm; 712 void *ctx; 713 714 PetscFunctionBegin; 715 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 716 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 717 PetscValidHeaderSpecific(Udot,VEC_CLASSID,4); 718 PetscValidPointer(A,6); 719 PetscValidHeaderSpecific(*A,MAT_CLASSID,6); 720 PetscValidPointer(B,7); 721 PetscValidHeaderSpecific(*B,MAT_CLASSID,7); 722 PetscValidPointer(flg,8); 723 724 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 725 ierr = DMTSGetIJacobian(dm,&ijacobian,&ctx);CHKERRQ(ierr); 726 ierr = DMTSGetRHSJacobian(dm,&rhsjacobian,NULL);CHKERRQ(ierr); 727 728 if (!rhsjacobian && !ijacobian) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()"); 729 730 *flg = SAME_NONZERO_PATTERN; /* In case we're solving a linear problem in which case it wouldn't get initialized below. */ 731 ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,*A,*B);CHKERRQ(ierr); 732 if (ijacobian) { 733 *flg = DIFFERENT_NONZERO_PATTERN; 734 PetscStackPush("TS user implicit Jacobian"); 735 ierr = (*ijacobian)(ts,t,U,Udot,shift,A,B,flg,ctx);CHKERRQ(ierr); 736 PetscStackPop; 737 /* make sure user returned a correct Jacobian and preconditioner */ 738 PetscValidHeaderSpecific(*A,MAT_CLASSID,4); 739 PetscValidHeaderSpecific(*B,MAT_CLASSID,5); 740 } 741 if (imex) { 742 if (!ijacobian) { /* system was written as Udot = G(t,U) */ 743 ierr = MatZeroEntries(*A);CHKERRQ(ierr); 744 ierr = MatShift(*A,shift);CHKERRQ(ierr); 745 if (*A != *B) { 746 ierr = MatZeroEntries(*B);CHKERRQ(ierr); 747 ierr = MatShift(*B,shift);CHKERRQ(ierr); 748 } 749 *flg = SAME_PRECONDITIONER; 750 } 751 } else { 752 Mat Arhs = NULL,Brhs = NULL; 753 MatStructure flg2; 754 if (rhsjacobian) { 755 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 756 ierr = TSComputeRHSJacobian(ts,t,U,&Arhs,&Brhs,&flg2);CHKERRQ(ierr); 757 } 758 if (Arhs == *A) { /* No IJacobian, so we only have the RHS matrix */ 759 ts->rhsjacobian.scale = -1; 760 ts->rhsjacobian.shift = shift; 761 ierr = MatScale(*A,-1);CHKERRQ(ierr); 762 ierr = MatShift(*A,shift);CHKERRQ(ierr); 763 if (*A != *B) { 764 ierr = MatScale(*B,-1);CHKERRQ(ierr); 765 ierr = MatShift(*B,shift);CHKERRQ(ierr); 766 } 767 } else if (Arhs) { /* Both IJacobian and RHSJacobian */ 768 MatStructure axpy = DIFFERENT_NONZERO_PATTERN; 769 if (!ijacobian) { /* No IJacobian provided, but we have a separate RHS matrix */ 770 ierr = MatZeroEntries(*A);CHKERRQ(ierr); 771 ierr = MatShift(*A,shift);CHKERRQ(ierr); 772 if (*A != *B) { 773 ierr = MatZeroEntries(*B);CHKERRQ(ierr); 774 ierr = MatShift(*B,shift);CHKERRQ(ierr); 775 } 776 } 777 ierr = MatAXPY(*A,-1,Arhs,axpy);CHKERRQ(ierr); 778 if (*A != *B) { 779 ierr = MatAXPY(*B,-1,Brhs,axpy);CHKERRQ(ierr); 780 } 781 *flg = PetscMin(*flg,flg2); 782 } 783 } 784 785 ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,*A,*B);CHKERRQ(ierr); 786 PetscFunctionReturn(0); 787 } 788 789 #undef __FUNCT__ 790 #define __FUNCT__ "TSSetRHSFunction" 791 /*@C 792 TSSetRHSFunction - Sets the routine for evaluating the function, 793 where U_t = G(t,u). 794 795 Logically Collective on TS 796 797 Input Parameters: 798 + ts - the TS context obtained from TSCreate() 799 . r - vector to put the computed right hand side (or NULL to have it created) 800 . f - routine for evaluating the right-hand-side function 801 - ctx - [optional] user-defined context for private data for the 802 function evaluation routine (may be NULL) 803 804 Calling sequence of func: 805 $ func (TS ts,PetscReal t,Vec u,Vec F,void *ctx); 806 807 + t - current timestep 808 . u - input vector 809 . F - function vector 810 - ctx - [optional] user-defined function context 811 812 Level: beginner 813 814 .keywords: TS, timestep, set, right-hand-side, function 815 816 .seealso: TSSetRHSJacobian(), TSSetIJacobian() 817 @*/ 818 PetscErrorCode TSSetRHSFunction(TS ts,Vec r,PetscErrorCode (*f)(TS,PetscReal,Vec,Vec,void*),void *ctx) 819 { 820 PetscErrorCode ierr; 821 SNES snes; 822 Vec ralloc = NULL; 823 DM dm; 824 825 PetscFunctionBegin; 826 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 827 if (r) PetscValidHeaderSpecific(r,VEC_CLASSID,2); 828 829 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 830 ierr = DMTSSetRHSFunction(dm,f,ctx);CHKERRQ(ierr); 831 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 832 if (!r && !ts->dm && ts->vec_sol) { 833 ierr = VecDuplicate(ts->vec_sol,&ralloc);CHKERRQ(ierr); 834 r = ralloc; 835 } 836 ierr = SNESSetFunction(snes,r,SNESTSFormFunction,ts);CHKERRQ(ierr); 837 ierr = VecDestroy(&ralloc);CHKERRQ(ierr); 838 PetscFunctionReturn(0); 839 } 840 841 #undef __FUNCT__ 842 #define __FUNCT__ "TSSetSolutionFunction" 843 /*@C 844 TSSetSolutionFunction - Provide a function that computes the solution of the ODE or DAE 845 846 Logically Collective on TS 847 848 Input Parameters: 849 + ts - the TS context obtained from TSCreate() 850 . f - routine for evaluating the solution 851 - ctx - [optional] user-defined context for private data for the 852 function evaluation routine (may be NULL) 853 854 Calling sequence of func: 855 $ func (TS ts,PetscReal t,Vec u,void *ctx); 856 857 + t - current timestep 858 . u - output vector 859 - ctx - [optional] user-defined function context 860 861 Notes: 862 This routine is used for testing accuracy of time integration schemes when you already know the solution. 863 If analytic solutions are not known for your system, consider using the Method of Manufactured Solutions to 864 create closed-form solutions with non-physical forcing terms. 865 866 For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history. 867 868 Level: beginner 869 870 .keywords: TS, timestep, set, right-hand-side, function 871 872 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetForcingFunction() 873 @*/ 874 PetscErrorCode TSSetSolutionFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,void*),void *ctx) 875 { 876 PetscErrorCode ierr; 877 DM dm; 878 879 PetscFunctionBegin; 880 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 881 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 882 ierr = DMTSSetSolutionFunction(dm,f,ctx);CHKERRQ(ierr); 883 PetscFunctionReturn(0); 884 } 885 886 #undef __FUNCT__ 887 #define __FUNCT__ "TSSetForcingFunction" 888 /*@C 889 TSSetForcingFunction - Provide a function that computes a forcing term for a ODE or PDE 890 891 Logically Collective on TS 892 893 Input Parameters: 894 + ts - the TS context obtained from TSCreate() 895 . f - routine for evaluating the forcing function 896 - ctx - [optional] user-defined context for private data for the 897 function evaluation routine (may be NULL) 898 899 Calling sequence of func: 900 $ func (TS ts,PetscReal t,Vec u,void *ctx); 901 902 + t - current timestep 903 . u - output vector 904 - ctx - [optional] user-defined function context 905 906 Notes: 907 This routine is useful for testing accuracy of time integration schemes when using the Method of Manufactured Solutions to 908 create closed-form solutions with a non-physical forcing term. 909 910 For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history. 911 912 Level: beginner 913 914 .keywords: TS, timestep, set, right-hand-side, function 915 916 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetSolutionFunction() 917 @*/ 918 PetscErrorCode TSSetForcingFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,void*),void *ctx) 919 { 920 PetscErrorCode ierr; 921 DM dm; 922 923 PetscFunctionBegin; 924 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 925 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 926 ierr = DMTSSetForcingFunction(dm,f,ctx);CHKERRQ(ierr); 927 PetscFunctionReturn(0); 928 } 929 930 #undef __FUNCT__ 931 #define __FUNCT__ "TSSetRHSJacobian" 932 /*@C 933 TSSetRHSJacobian - Sets the function to compute the Jacobian of F, 934 where U_t = G(U,t), as well as the location to store the matrix. 935 936 Logically Collective on TS 937 938 Input Parameters: 939 + ts - the TS context obtained from TSCreate() 940 . Amat - (approximate) Jacobian matrix 941 . Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat) 942 . f - the Jacobian evaluation routine 943 - ctx - [optional] user-defined context for private data for the 944 Jacobian evaluation routine (may be NULL) 945 946 Calling sequence of func: 947 $ func (TS ts,PetscReal t,Vec u,Mat *A,Mat *B,MatStructure *flag,void *ctx); 948 949 + t - current timestep 950 . u - input vector 951 . Amat - (approximate) Jacobian matrix 952 . Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat) 953 . flag - flag indicating information about the preconditioner matrix 954 structure (same as flag in KSPSetOperators()) 955 - ctx - [optional] user-defined context for matrix evaluation routine 956 957 Notes: 958 See KSPSetOperators() for important information about setting the flag 959 output parameter in the routine func(). Be sure to read this information! 960 961 The routine func() takes Mat * as the matrix arguments rather than Mat. 962 This allows the matrix evaluation routine to replace A and/or B with a 963 completely new matrix structure (not just different matrix elements) 964 when appropriate, for instance, if the nonzero structure is changing 965 throughout the global iterations. 966 967 Level: beginner 968 969 .keywords: TS, timestep, set, right-hand-side, Jacobian 970 971 .seealso: SNESComputeJacobianDefaultColor(), TSSetRHSFunction(), TSRHSJacobianSetReuse() 972 973 @*/ 974 PetscErrorCode TSSetRHSJacobian(TS ts,Mat Amat,Mat Pmat,TSRHSJacobian f,void *ctx) 975 { 976 PetscErrorCode ierr; 977 SNES snes; 978 DM dm; 979 TSIJacobian ijacobian; 980 981 PetscFunctionBegin; 982 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 983 if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 984 if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 985 if (Amat) PetscCheckSameComm(ts,1,Amat,2); 986 if (Pmat) PetscCheckSameComm(ts,1,Pmat,3); 987 988 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 989 ierr = DMTSSetRHSJacobian(dm,f,ctx);CHKERRQ(ierr); 990 if (f == TSComputeRHSJacobianConstant) { 991 /* Handle this case automatically for the user; otherwise user should call themselves. */ 992 ierr = TSRHSJacobianSetReuse(ts,PETSC_TRUE);CHKERRQ(ierr); 993 } 994 ierr = DMTSGetIJacobian(dm,&ijacobian,NULL);CHKERRQ(ierr); 995 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 996 if (!ijacobian) { 997 ierr = SNESSetJacobian(snes,Amat,Pmat,SNESTSFormJacobian,ts);CHKERRQ(ierr); 998 } 999 if (Amat) { 1000 ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 1001 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 1002 1003 ts->Arhs = Amat; 1004 } 1005 if (Pmat) { 1006 ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr); 1007 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 1008 1009 ts->Brhs = Pmat; 1010 } 1011 PetscFunctionReturn(0); 1012 } 1013 1014 1015 #undef __FUNCT__ 1016 #define __FUNCT__ "TSSetIFunction" 1017 /*@C 1018 TSSetIFunction - Set the function to compute F(t,U,U_t) where F() = 0 is the DAE to be solved. 1019 1020 Logically Collective on TS 1021 1022 Input Parameters: 1023 + ts - the TS context obtained from TSCreate() 1024 . r - vector to hold the residual (or NULL to have it created internally) 1025 . f - the function evaluation routine 1026 - ctx - user-defined context for private data for the function evaluation routine (may be NULL) 1027 1028 Calling sequence of f: 1029 $ f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx); 1030 1031 + t - time at step/stage being solved 1032 . u - state vector 1033 . u_t - time derivative of state vector 1034 . F - function vector 1035 - ctx - [optional] user-defined context for matrix evaluation routine 1036 1037 Important: 1038 The user MUST call either this routine, TSSetRHSFunction(). This routine must be used when not solving an ODE, for example a DAE. 1039 1040 Level: beginner 1041 1042 .keywords: TS, timestep, set, DAE, Jacobian 1043 1044 .seealso: TSSetRHSJacobian(), TSSetRHSFunction(), TSSetIJacobian() 1045 @*/ 1046 PetscErrorCode TSSetIFunction(TS ts,Vec res,TSIFunction f,void *ctx) 1047 { 1048 PetscErrorCode ierr; 1049 SNES snes; 1050 Vec resalloc = NULL; 1051 DM dm; 1052 1053 PetscFunctionBegin; 1054 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1055 if (res) PetscValidHeaderSpecific(res,VEC_CLASSID,2); 1056 1057 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1058 ierr = DMTSSetIFunction(dm,f,ctx);CHKERRQ(ierr); 1059 1060 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1061 if (!res && !ts->dm && ts->vec_sol) { 1062 ierr = VecDuplicate(ts->vec_sol,&resalloc);CHKERRQ(ierr); 1063 res = resalloc; 1064 } 1065 ierr = SNESSetFunction(snes,res,SNESTSFormFunction,ts);CHKERRQ(ierr); 1066 ierr = VecDestroy(&resalloc);CHKERRQ(ierr); 1067 PetscFunctionReturn(0); 1068 } 1069 1070 #undef __FUNCT__ 1071 #define __FUNCT__ "TSGetIFunction" 1072 /*@C 1073 TSGetIFunction - Returns the vector where the implicit residual is stored and the function/contex to compute it. 1074 1075 Not Collective 1076 1077 Input Parameter: 1078 . ts - the TS context 1079 1080 Output Parameter: 1081 + r - vector to hold residual (or NULL) 1082 . func - the function to compute residual (or NULL) 1083 - ctx - the function context (or NULL) 1084 1085 Level: advanced 1086 1087 .keywords: TS, nonlinear, get, function 1088 1089 .seealso: TSSetIFunction(), SNESGetFunction() 1090 @*/ 1091 PetscErrorCode TSGetIFunction(TS ts,Vec *r,TSIFunction *func,void **ctx) 1092 { 1093 PetscErrorCode ierr; 1094 SNES snes; 1095 DM dm; 1096 1097 PetscFunctionBegin; 1098 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1099 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1100 ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 1101 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1102 ierr = DMTSGetIFunction(dm,func,ctx);CHKERRQ(ierr); 1103 PetscFunctionReturn(0); 1104 } 1105 1106 #undef __FUNCT__ 1107 #define __FUNCT__ "TSGetRHSFunction" 1108 /*@C 1109 TSGetRHSFunction - Returns the vector where the right hand side is stored and the function/context to compute it. 1110 1111 Not Collective 1112 1113 Input Parameter: 1114 . ts - the TS context 1115 1116 Output Parameter: 1117 + r - vector to hold computed right hand side (or NULL) 1118 . func - the function to compute right hand side (or NULL) 1119 - ctx - the function context (or NULL) 1120 1121 Level: advanced 1122 1123 .keywords: TS, nonlinear, get, function 1124 1125 .seealso: TSSetRhsfunction(), SNESGetFunction() 1126 @*/ 1127 PetscErrorCode TSGetRHSFunction(TS ts,Vec *r,TSRHSFunction *func,void **ctx) 1128 { 1129 PetscErrorCode ierr; 1130 SNES snes; 1131 DM dm; 1132 1133 PetscFunctionBegin; 1134 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1135 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1136 ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 1137 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1138 ierr = DMTSGetRHSFunction(dm,func,ctx);CHKERRQ(ierr); 1139 PetscFunctionReturn(0); 1140 } 1141 1142 #undef __FUNCT__ 1143 #define __FUNCT__ "TSSetIJacobian" 1144 /*@C 1145 TSSetIJacobian - Set the function to compute the matrix dF/dU + a*dF/dU_t where F(t,U,U_t) is the function 1146 you provided with TSSetIFunction(). 1147 1148 Logically Collective on TS 1149 1150 Input Parameters: 1151 + ts - the TS context obtained from TSCreate() 1152 . Amat - (approximate) Jacobian matrix 1153 . Pmat - matrix used to compute preconditioner (usually the same as Amat) 1154 . f - the Jacobian evaluation routine 1155 - ctx - user-defined context for private data for the Jacobian evaluation routine (may be NULL) 1156 1157 Calling sequence of f: 1158 $ f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat *Amat,Mat *Pmat,MatStructure *flag,void *ctx); 1159 1160 + t - time at step/stage being solved 1161 . U - state vector 1162 . U_t - time derivative of state vector 1163 . a - shift 1164 . Amat - (approximate) Jacobian of F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t 1165 . Pmat - matrix used for constructing preconditioner, usually the same as Amat 1166 . flag - flag indicating information about the preconditioner matrix 1167 structure (same as flag in KSPSetOperators()) 1168 - ctx - [optional] user-defined context for matrix evaluation routine 1169 1170 Notes: 1171 The matrices Amat and Pmat are exactly the matrices that are used by SNES for the nonlinear solve. 1172 1173 The matrix dF/dU + a*dF/dU_t you provide turns out to be 1174 the Jacobian of F(t,U,W+a*U) where F(t,U,U_t) = 0 is the DAE to be solved. 1175 The time integrator internally approximates U_t by W+a*U where the positive "shift" 1176 a and vector W depend on the integration method, step size, and past states. For example with 1177 the backward Euler method a = 1/dt and W = -a*U(previous timestep) so 1178 W + a*U = a*(U - U(previous timestep)) = (U - U(previous timestep))/dt 1179 1180 Level: beginner 1181 1182 .keywords: TS, timestep, DAE, Jacobian 1183 1184 .seealso: TSSetIFunction(), TSSetRHSJacobian(), SNESComputeJacobianDefaultColor(), SNESComputeJacobianDefault() 1185 1186 @*/ 1187 PetscErrorCode TSSetIJacobian(TS ts,Mat Amat,Mat Pmat,TSIJacobian f,void *ctx) 1188 { 1189 PetscErrorCode ierr; 1190 SNES snes; 1191 DM dm; 1192 1193 PetscFunctionBegin; 1194 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1195 if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 1196 if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 1197 if (Amat) PetscCheckSameComm(ts,1,Amat,2); 1198 if (Pmat) PetscCheckSameComm(ts,1,Pmat,3); 1199 1200 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1201 ierr = DMTSSetIJacobian(dm,f,ctx);CHKERRQ(ierr); 1202 1203 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1204 ierr = SNESSetJacobian(snes,Amat,Pmat,SNESTSFormJacobian,ts);CHKERRQ(ierr); 1205 PetscFunctionReturn(0); 1206 } 1207 1208 #undef __FUNCT__ 1209 #define __FUNCT__ "TSRHSJacobianSetReuse" 1210 /*@ 1211 TSRHSJacobianSetReuse - restore RHS Jacobian before re-evaluating. Without this flag, TS will change the sign and 1212 shift the RHS Jacobian for a finite-time-step implicit solve, in which case the user function will need to recompute 1213 the entire Jacobian. The reuse flag must be set if the evaluation function will assume that the matrix entries have 1214 not been changed by the TS. 1215 1216 Logically Collective 1217 1218 Input Arguments: 1219 + ts - TS context obtained from TSCreate() 1220 - reuse - PETSC_TRUE if the RHS Jacobian 1221 1222 Level: intermediate 1223 1224 .seealso: TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 1225 @*/ 1226 PetscErrorCode TSRHSJacobianSetReuse(TS ts,PetscBool reuse) 1227 { 1228 PetscFunctionBegin; 1229 ts->rhsjacobian.reuse = reuse; 1230 PetscFunctionReturn(0); 1231 } 1232 1233 #undef __FUNCT__ 1234 #define __FUNCT__ "TSLoad" 1235 /*@C 1236 TSLoad - Loads a KSP that has been stored in binary with KSPView(). 1237 1238 Collective on PetscViewer 1239 1240 Input Parameters: 1241 + newdm - the newly loaded TS, this needs to have been created with TSCreate() or 1242 some related function before a call to TSLoad(). 1243 - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() 1244 1245 Level: intermediate 1246 1247 Notes: 1248 The type is determined by the data in the file, any type set into the TS before this call is ignored. 1249 1250 Notes for advanced users: 1251 Most users should not need to know the details of the binary storage 1252 format, since TSLoad() and TSView() completely hide these details. 1253 But for anyone who's interested, the standard binary matrix storage 1254 format is 1255 .vb 1256 has not yet been determined 1257 .ve 1258 1259 .seealso: PetscViewerBinaryOpen(), TSView(), MatLoad(), VecLoad() 1260 @*/ 1261 PetscErrorCode TSLoad(TS ts, PetscViewer viewer) 1262 { 1263 PetscErrorCode ierr; 1264 PetscBool isbinary; 1265 PetscInt classid; 1266 char type[256]; 1267 DMTS sdm; 1268 DM dm; 1269 1270 PetscFunctionBegin; 1271 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1272 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1273 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1274 if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 1275 1276 ierr = PetscViewerBinaryRead(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr); 1277 if (classid != TS_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Not TS next in file"); 1278 ierr = PetscViewerBinaryRead(viewer,type,256,PETSC_CHAR);CHKERRQ(ierr); 1279 ierr = TSSetType(ts, type);CHKERRQ(ierr); 1280 if (ts->ops->load) { 1281 ierr = (*ts->ops->load)(ts,viewer);CHKERRQ(ierr); 1282 } 1283 ierr = DMCreate(PetscObjectComm((PetscObject)ts),&dm);CHKERRQ(ierr); 1284 ierr = DMLoad(dm,viewer);CHKERRQ(ierr); 1285 ierr = TSSetDM(ts,dm);CHKERRQ(ierr); 1286 ierr = DMCreateGlobalVector(ts->dm,&ts->vec_sol);CHKERRQ(ierr); 1287 ierr = VecLoad(ts->vec_sol,viewer);CHKERRQ(ierr); 1288 ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr); 1289 ierr = DMTSLoad(sdm,viewer);CHKERRQ(ierr); 1290 PetscFunctionReturn(0); 1291 } 1292 1293 #include <petscdraw.h> 1294 #if defined(PETSC_HAVE_SAWS) 1295 #include <petscviewersaws.h> 1296 #endif 1297 #undef __FUNCT__ 1298 #define __FUNCT__ "TSView" 1299 /*@C 1300 TSView - Prints the TS data structure. 1301 1302 Collective on TS 1303 1304 Input Parameters: 1305 + ts - the TS context obtained from TSCreate() 1306 - viewer - visualization context 1307 1308 Options Database Key: 1309 . -ts_view - calls TSView() at end of TSStep() 1310 1311 Notes: 1312 The available visualization contexts include 1313 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 1314 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 1315 output where only the first processor opens 1316 the file. All other processors send their 1317 data to the first processor to print. 1318 1319 The user can open an alternative visualization context with 1320 PetscViewerASCIIOpen() - output to a specified file. 1321 1322 Level: beginner 1323 1324 .keywords: TS, timestep, view 1325 1326 .seealso: PetscViewerASCIIOpen() 1327 @*/ 1328 PetscErrorCode TSView(TS ts,PetscViewer viewer) 1329 { 1330 PetscErrorCode ierr; 1331 TSType type; 1332 PetscBool iascii,isstring,isundials,isbinary,isdraw; 1333 DMTS sdm; 1334 #if defined(PETSC_HAVE_SAWS) 1335 PetscBool isams; 1336 #endif 1337 1338 PetscFunctionBegin; 1339 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1340 if (!viewer) { 1341 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ts),&viewer);CHKERRQ(ierr); 1342 } 1343 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1344 PetscCheckSameComm(ts,1,viewer,2); 1345 1346 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1347 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 1348 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1349 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 1350 #if defined(PETSC_HAVE_SAWS) 1351 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&isams);CHKERRQ(ierr); 1352 #endif 1353 if (iascii) { 1354 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ts,viewer);CHKERRQ(ierr); 1355 ierr = PetscViewerASCIIPrintf(viewer," maximum steps=%D\n",ts->max_steps);CHKERRQ(ierr); 1356 ierr = PetscViewerASCIIPrintf(viewer," maximum time=%G\n",ts->max_time);CHKERRQ(ierr); 1357 if (ts->problem_type == TS_NONLINEAR) { 1358 ierr = PetscViewerASCIIPrintf(viewer," total number of nonlinear solver iterations=%D\n",ts->snes_its);CHKERRQ(ierr); 1359 ierr = PetscViewerASCIIPrintf(viewer," total number of nonlinear solve failures=%D\n",ts->num_snes_failures);CHKERRQ(ierr); 1360 } 1361 ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",ts->ksp_its);CHKERRQ(ierr); 1362 ierr = PetscViewerASCIIPrintf(viewer," total number of rejected steps=%D\n",ts->reject);CHKERRQ(ierr); 1363 ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr); 1364 ierr = DMTSView(sdm,viewer);CHKERRQ(ierr); 1365 if (ts->ops->view) { 1366 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1367 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 1368 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1369 } 1370 } else if (isstring) { 1371 ierr = TSGetType(ts,&type);CHKERRQ(ierr); 1372 ierr = PetscViewerStringSPrintf(viewer," %-7.7s",type);CHKERRQ(ierr); 1373 } else if (isbinary) { 1374 PetscInt classid = TS_FILE_CLASSID; 1375 MPI_Comm comm; 1376 PetscMPIInt rank; 1377 char type[256]; 1378 1379 ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr); 1380 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 1381 if (!rank) { 1382 ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 1383 ierr = PetscStrncpy(type,((PetscObject)ts)->type_name,256);CHKERRQ(ierr); 1384 ierr = PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 1385 } 1386 if (ts->ops->view) { 1387 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 1388 } 1389 ierr = DMView(ts->dm,viewer);CHKERRQ(ierr); 1390 ierr = VecView(ts->vec_sol,viewer);CHKERRQ(ierr); 1391 ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr); 1392 ierr = DMTSView(sdm,viewer);CHKERRQ(ierr); 1393 } else if (isdraw) { 1394 PetscDraw draw; 1395 char str[36]; 1396 PetscReal x,y,bottom,h; 1397 1398 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 1399 ierr = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr); 1400 ierr = PetscStrcpy(str,"TS: ");CHKERRQ(ierr); 1401 ierr = PetscStrcat(str,((PetscObject)ts)->type_name);CHKERRQ(ierr); 1402 ierr = PetscDrawBoxedString(draw,x,y,PETSC_DRAW_BLACK,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr); 1403 bottom = y - h; 1404 ierr = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr); 1405 if (ts->ops->view) { 1406 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 1407 } 1408 ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr); 1409 #if defined(PETSC_HAVE_SAWS) 1410 } else if (isams) { 1411 PetscMPIInt rank; 1412 const char *name; 1413 1414 ierr = PetscObjectGetName((PetscObject)ts,&name);CHKERRQ(ierr); 1415 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 1416 if (!((PetscObject)ts)->amsmem && !rank) { 1417 char dir[1024]; 1418 1419 ierr = PetscObjectViewSAWs((PetscObject)ts,viewer);CHKERRQ(ierr); 1420 ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time_step",name);CHKERRQ(ierr); 1421 PetscStackCallSAWs(SAWs_Register,(dir,&ts->steps,1,SAWs_READ,SAWs_INT)); 1422 ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time",name);CHKERRQ(ierr); 1423 PetscStackCallSAWs(SAWs_Register,(dir,&ts->ptime,1,SAWs_READ,SAWs_DOUBLE)); 1424 } 1425 if (ts->ops->view) { 1426 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 1427 } 1428 #endif 1429 } 1430 1431 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1432 ierr = PetscObjectTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials);CHKERRQ(ierr); 1433 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1434 PetscFunctionReturn(0); 1435 } 1436 1437 1438 #undef __FUNCT__ 1439 #define __FUNCT__ "TSSetApplicationContext" 1440 /*@ 1441 TSSetApplicationContext - Sets an optional user-defined context for 1442 the timesteppers. 1443 1444 Logically Collective on TS 1445 1446 Input Parameters: 1447 + ts - the TS context obtained from TSCreate() 1448 - usrP - optional user context 1449 1450 Level: intermediate 1451 1452 .keywords: TS, timestep, set, application, context 1453 1454 .seealso: TSGetApplicationContext() 1455 @*/ 1456 PetscErrorCode TSSetApplicationContext(TS ts,void *usrP) 1457 { 1458 PetscFunctionBegin; 1459 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1460 ts->user = usrP; 1461 PetscFunctionReturn(0); 1462 } 1463 1464 #undef __FUNCT__ 1465 #define __FUNCT__ "TSGetApplicationContext" 1466 /*@ 1467 TSGetApplicationContext - Gets the user-defined context for the 1468 timestepper. 1469 1470 Not Collective 1471 1472 Input Parameter: 1473 . ts - the TS context obtained from TSCreate() 1474 1475 Output Parameter: 1476 . usrP - user context 1477 1478 Level: intermediate 1479 1480 .keywords: TS, timestep, get, application, context 1481 1482 .seealso: TSSetApplicationContext() 1483 @*/ 1484 PetscErrorCode TSGetApplicationContext(TS ts,void *usrP) 1485 { 1486 PetscFunctionBegin; 1487 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1488 *(void**)usrP = ts->user; 1489 PetscFunctionReturn(0); 1490 } 1491 1492 #undef __FUNCT__ 1493 #define __FUNCT__ "TSGetTimeStepNumber" 1494 /*@ 1495 TSGetTimeStepNumber - Gets the number of time steps completed. 1496 1497 Not Collective 1498 1499 Input Parameter: 1500 . ts - the TS context obtained from TSCreate() 1501 1502 Output Parameter: 1503 . iter - number of steps completed so far 1504 1505 Level: intermediate 1506 1507 .keywords: TS, timestep, get, iteration, number 1508 .seealso: TSGetTime(), TSGetTimeStep(), TSSetPreStep(), TSSetPreStage(), TSSetPostStep() 1509 @*/ 1510 PetscErrorCode TSGetTimeStepNumber(TS ts,PetscInt *iter) 1511 { 1512 PetscFunctionBegin; 1513 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1514 PetscValidIntPointer(iter,2); 1515 *iter = ts->steps; 1516 PetscFunctionReturn(0); 1517 } 1518 1519 #undef __FUNCT__ 1520 #define __FUNCT__ "TSSetInitialTimeStep" 1521 /*@ 1522 TSSetInitialTimeStep - Sets the initial timestep to be used, 1523 as well as the initial time. 1524 1525 Logically Collective on TS 1526 1527 Input Parameters: 1528 + ts - the TS context obtained from TSCreate() 1529 . initial_time - the initial time 1530 - time_step - the size of the timestep 1531 1532 Level: intermediate 1533 1534 .seealso: TSSetTimeStep(), TSGetTimeStep() 1535 1536 .keywords: TS, set, initial, timestep 1537 @*/ 1538 PetscErrorCode TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step) 1539 { 1540 PetscErrorCode ierr; 1541 1542 PetscFunctionBegin; 1543 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1544 ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr); 1545 ierr = TSSetTime(ts,initial_time);CHKERRQ(ierr); 1546 PetscFunctionReturn(0); 1547 } 1548 1549 #undef __FUNCT__ 1550 #define __FUNCT__ "TSSetTimeStep" 1551 /*@ 1552 TSSetTimeStep - Allows one to reset the timestep at any time, 1553 useful for simple pseudo-timestepping codes. 1554 1555 Logically Collective on TS 1556 1557 Input Parameters: 1558 + ts - the TS context obtained from TSCreate() 1559 - time_step - the size of the timestep 1560 1561 Level: intermediate 1562 1563 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 1564 1565 .keywords: TS, set, timestep 1566 @*/ 1567 PetscErrorCode TSSetTimeStep(TS ts,PetscReal time_step) 1568 { 1569 PetscFunctionBegin; 1570 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1571 PetscValidLogicalCollectiveReal(ts,time_step,2); 1572 ts->time_step = time_step; 1573 ts->time_step_orig = time_step; 1574 PetscFunctionReturn(0); 1575 } 1576 1577 #undef __FUNCT__ 1578 #define __FUNCT__ "TSSetExactFinalTime" 1579 /*@ 1580 TSSetExactFinalTime - Determines whether to adapt the final time step to 1581 match the exact final time, interpolate solution to the exact final time, 1582 or just return at the final time TS computed. 1583 1584 Logically Collective on TS 1585 1586 Input Parameter: 1587 + ts - the time-step context 1588 - eftopt - exact final time option 1589 1590 Level: beginner 1591 1592 .seealso: TSExactFinalTimeOption 1593 @*/ 1594 PetscErrorCode TSSetExactFinalTime(TS ts,TSExactFinalTimeOption eftopt) 1595 { 1596 PetscFunctionBegin; 1597 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1598 PetscValidLogicalCollectiveEnum(ts,eftopt,2); 1599 ts->exact_final_time = eftopt; 1600 PetscFunctionReturn(0); 1601 } 1602 1603 #undef __FUNCT__ 1604 #define __FUNCT__ "TSGetTimeStep" 1605 /*@ 1606 TSGetTimeStep - Gets the current timestep size. 1607 1608 Not Collective 1609 1610 Input Parameter: 1611 . ts - the TS context obtained from TSCreate() 1612 1613 Output Parameter: 1614 . dt - the current timestep size 1615 1616 Level: intermediate 1617 1618 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 1619 1620 .keywords: TS, get, timestep 1621 @*/ 1622 PetscErrorCode TSGetTimeStep(TS ts,PetscReal *dt) 1623 { 1624 PetscFunctionBegin; 1625 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1626 PetscValidRealPointer(dt,2); 1627 *dt = ts->time_step; 1628 PetscFunctionReturn(0); 1629 } 1630 1631 #undef __FUNCT__ 1632 #define __FUNCT__ "TSGetSolution" 1633 /*@ 1634 TSGetSolution - Returns the solution at the present timestep. It 1635 is valid to call this routine inside the function that you are evaluating 1636 in order to move to the new timestep. This vector not changed until 1637 the solution at the next timestep has been calculated. 1638 1639 Not Collective, but Vec returned is parallel if TS is parallel 1640 1641 Input Parameter: 1642 . ts - the TS context obtained from TSCreate() 1643 1644 Output Parameter: 1645 . v - the vector containing the solution 1646 1647 Level: intermediate 1648 1649 .seealso: TSGetTimeStep() 1650 1651 .keywords: TS, timestep, get, solution 1652 @*/ 1653 PetscErrorCode TSGetSolution(TS ts,Vec *v) 1654 { 1655 PetscFunctionBegin; 1656 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1657 PetscValidPointer(v,2); 1658 *v = ts->vec_sol; 1659 PetscFunctionReturn(0); 1660 } 1661 1662 /* ----- Routines to initialize and destroy a timestepper ---- */ 1663 #undef __FUNCT__ 1664 #define __FUNCT__ "TSSetProblemType" 1665 /*@ 1666 TSSetProblemType - Sets the type of problem to be solved. 1667 1668 Not collective 1669 1670 Input Parameters: 1671 + ts - The TS 1672 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 1673 .vb 1674 U_t - A U = 0 (linear) 1675 U_t - A(t) U = 0 (linear) 1676 F(t,U,U_t) = 0 (nonlinear) 1677 .ve 1678 1679 Level: beginner 1680 1681 .keywords: TS, problem type 1682 .seealso: TSSetUp(), TSProblemType, TS 1683 @*/ 1684 PetscErrorCode TSSetProblemType(TS ts, TSProblemType type) 1685 { 1686 PetscErrorCode ierr; 1687 1688 PetscFunctionBegin; 1689 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1690 ts->problem_type = type; 1691 if (type == TS_LINEAR) { 1692 SNES snes; 1693 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1694 ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr); 1695 } 1696 PetscFunctionReturn(0); 1697 } 1698 1699 #undef __FUNCT__ 1700 #define __FUNCT__ "TSGetProblemType" 1701 /*@C 1702 TSGetProblemType - Gets the type of problem to be solved. 1703 1704 Not collective 1705 1706 Input Parameter: 1707 . ts - The TS 1708 1709 Output Parameter: 1710 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 1711 .vb 1712 M U_t = A U 1713 M(t) U_t = A(t) U 1714 F(t,U,U_t) 1715 .ve 1716 1717 Level: beginner 1718 1719 .keywords: TS, problem type 1720 .seealso: TSSetUp(), TSProblemType, TS 1721 @*/ 1722 PetscErrorCode TSGetProblemType(TS ts, TSProblemType *type) 1723 { 1724 PetscFunctionBegin; 1725 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1726 PetscValidIntPointer(type,2); 1727 *type = ts->problem_type; 1728 PetscFunctionReturn(0); 1729 } 1730 1731 #undef __FUNCT__ 1732 #define __FUNCT__ "TSSetUp" 1733 /*@ 1734 TSSetUp - Sets up the internal data structures for the later use 1735 of a timestepper. 1736 1737 Collective on TS 1738 1739 Input Parameter: 1740 . ts - the TS context obtained from TSCreate() 1741 1742 Notes: 1743 For basic use of the TS solvers the user need not explicitly call 1744 TSSetUp(), since these actions will automatically occur during 1745 the call to TSStep(). However, if one wishes to control this 1746 phase separately, TSSetUp() should be called after TSCreate() 1747 and optional routines of the form TSSetXXX(), but before TSStep(). 1748 1749 Level: advanced 1750 1751 .keywords: TS, timestep, setup 1752 1753 .seealso: TSCreate(), TSStep(), TSDestroy() 1754 @*/ 1755 PetscErrorCode TSSetUp(TS ts) 1756 { 1757 PetscErrorCode ierr; 1758 DM dm; 1759 PetscErrorCode (*func)(SNES,Vec,Vec,void*); 1760 PetscErrorCode (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 1761 TSIJacobian ijac; 1762 TSRHSJacobian rhsjac; 1763 1764 PetscFunctionBegin; 1765 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1766 if (ts->setupcalled) PetscFunctionReturn(0); 1767 1768 if (!((PetscObject)ts)->type_name) { 1769 ierr = TSSetType(ts,TSEULER);CHKERRQ(ierr); 1770 } 1771 1772 if (!ts->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first"); 1773 1774 ierr = TSGetAdapt(ts,&ts->adapt);CHKERRQ(ierr); 1775 1776 if (ts->rhsjacobian.reuse) { 1777 Mat Amat,Pmat; 1778 SNES snes; 1779 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1780 ierr = SNESGetJacobian(snes,&Amat,&Pmat,NULL,NULL);CHKERRQ(ierr); 1781 /* Matching matrices implies that an IJacobian is NOT set, because if it had been set, the IJacobian's matrix would 1782 * have displaced the RHS matrix */ 1783 if (Amat == ts->Arhs) { 1784 ierr = MatDuplicate(ts->Arhs,MAT_DO_NOT_COPY_VALUES,&Amat);CHKERRQ(ierr); 1785 ierr = SNESSetJacobian(snes,Amat,NULL,NULL,NULL);CHKERRQ(ierr); 1786 ierr = MatDestroy(&Amat);CHKERRQ(ierr); 1787 } 1788 if (Pmat == ts->Brhs) { 1789 ierr = MatDuplicate(ts->Brhs,MAT_DO_NOT_COPY_VALUES,&Pmat);CHKERRQ(ierr); 1790 ierr = SNESSetJacobian(snes,NULL,Pmat,NULL,NULL);CHKERRQ(ierr); 1791 ierr = MatDestroy(&Pmat);CHKERRQ(ierr); 1792 } 1793 } 1794 1795 if (ts->ops->setup) { 1796 ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr); 1797 } 1798 1799 /* in the case where we've set a DMTSFunction or what have you, we need the default SNESFunction 1800 to be set right but can't do it elsewhere due to the overreliance on ctx=ts. 1801 */ 1802 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1803 ierr = DMSNESGetFunction(dm,&func,NULL);CHKERRQ(ierr); 1804 if (!func) { 1805 ierr =DMSNESSetFunction(dm,SNESTSFormFunction,ts);CHKERRQ(ierr); 1806 } 1807 /* if the SNES doesn't have a jacobian set and the TS has an ijacobian or rhsjacobian set, set the SNES to use it. 1808 Otherwise, the SNES will use coloring internally to form the Jacobian. 1809 */ 1810 ierr = DMSNESGetJacobian(dm,&jac,NULL);CHKERRQ(ierr); 1811 ierr = DMTSGetIJacobian(dm,&ijac,NULL);CHKERRQ(ierr); 1812 ierr = DMTSGetRHSJacobian(dm,&rhsjac,NULL);CHKERRQ(ierr); 1813 if (!jac && (ijac || rhsjac)) { 1814 ierr = DMSNESSetJacobian(dm,SNESTSFormJacobian,ts);CHKERRQ(ierr); 1815 } 1816 ts->setupcalled = PETSC_TRUE; 1817 PetscFunctionReturn(0); 1818 } 1819 1820 #undef __FUNCT__ 1821 #define __FUNCT__ "TSReset" 1822 /*@ 1823 TSReset - Resets a TS context and removes any allocated Vecs and Mats. 1824 1825 Collective on TS 1826 1827 Input Parameter: 1828 . ts - the TS context obtained from TSCreate() 1829 1830 Level: beginner 1831 1832 .keywords: TS, timestep, reset 1833 1834 .seealso: TSCreate(), TSSetup(), TSDestroy() 1835 @*/ 1836 PetscErrorCode TSReset(TS ts) 1837 { 1838 PetscErrorCode ierr; 1839 1840 PetscFunctionBegin; 1841 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1842 if (ts->ops->reset) { 1843 ierr = (*ts->ops->reset)(ts);CHKERRQ(ierr); 1844 } 1845 if (ts->snes) {ierr = SNESReset(ts->snes);CHKERRQ(ierr);} 1846 1847 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 1848 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 1849 ierr = VecDestroy(&ts->Frhs);CHKERRQ(ierr); 1850 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 1851 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 1852 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 1853 ierr = VecDestroyVecs(ts->nwork,&ts->work);CHKERRQ(ierr); 1854 1855 ts->setupcalled = PETSC_FALSE; 1856 PetscFunctionReturn(0); 1857 } 1858 1859 #undef __FUNCT__ 1860 #define __FUNCT__ "TSDestroy" 1861 /*@ 1862 TSDestroy - Destroys the timestepper context that was created 1863 with TSCreate(). 1864 1865 Collective on TS 1866 1867 Input Parameter: 1868 . ts - the TS context obtained from TSCreate() 1869 1870 Level: beginner 1871 1872 .keywords: TS, timestepper, destroy 1873 1874 .seealso: TSCreate(), TSSetUp(), TSSolve() 1875 @*/ 1876 PetscErrorCode TSDestroy(TS *ts) 1877 { 1878 PetscErrorCode ierr; 1879 1880 PetscFunctionBegin; 1881 if (!*ts) PetscFunctionReturn(0); 1882 PetscValidHeaderSpecific((*ts),TS_CLASSID,1); 1883 if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; PetscFunctionReturn(0);} 1884 1885 ierr = TSReset((*ts));CHKERRQ(ierr); 1886 1887 /* if memory was published with SAWs then destroy it */ 1888 ierr = PetscObjectSAWsViewOff((PetscObject)*ts);CHKERRQ(ierr); 1889 if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);} 1890 1891 ierr = TSAdaptDestroy(&(*ts)->adapt);CHKERRQ(ierr); 1892 ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr); 1893 ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr); 1894 ierr = TSMonitorCancel((*ts));CHKERRQ(ierr); 1895 1896 ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr); 1897 PetscFunctionReturn(0); 1898 } 1899 1900 #undef __FUNCT__ 1901 #define __FUNCT__ "TSGetSNES" 1902 /*@ 1903 TSGetSNES - Returns the SNES (nonlinear solver) associated with 1904 a TS (timestepper) context. Valid only for nonlinear problems. 1905 1906 Not Collective, but SNES is parallel if TS is parallel 1907 1908 Input Parameter: 1909 . ts - the TS context obtained from TSCreate() 1910 1911 Output Parameter: 1912 . snes - the nonlinear solver context 1913 1914 Notes: 1915 The user can then directly manipulate the SNES context to set various 1916 options, etc. Likewise, the user can then extract and manipulate the 1917 KSP, KSP, and PC contexts as well. 1918 1919 TSGetSNES() does not work for integrators that do not use SNES; in 1920 this case TSGetSNES() returns NULL in snes. 1921 1922 Level: beginner 1923 1924 .keywords: timestep, get, SNES 1925 @*/ 1926 PetscErrorCode TSGetSNES(TS ts,SNES *snes) 1927 { 1928 PetscErrorCode ierr; 1929 1930 PetscFunctionBegin; 1931 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1932 PetscValidPointer(snes,2); 1933 if (!ts->snes) { 1934 ierr = SNESCreate(PetscObjectComm((PetscObject)ts),&ts->snes);CHKERRQ(ierr); 1935 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 1936 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->snes);CHKERRQ(ierr); 1937 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr); 1938 if (ts->dm) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 1939 if (ts->problem_type == TS_LINEAR) { 1940 ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr); 1941 } 1942 } 1943 *snes = ts->snes; 1944 PetscFunctionReturn(0); 1945 } 1946 1947 #undef __FUNCT__ 1948 #define __FUNCT__ "TSSetSNES" 1949 /*@ 1950 TSSetSNES - Set the SNES (nonlinear solver) to be used by the timestepping context 1951 1952 Collective 1953 1954 Input Parameter: 1955 + ts - the TS context obtained from TSCreate() 1956 - snes - the nonlinear solver context 1957 1958 Notes: 1959 Most users should have the TS created by calling TSGetSNES() 1960 1961 Level: developer 1962 1963 .keywords: timestep, set, SNES 1964 @*/ 1965 PetscErrorCode TSSetSNES(TS ts,SNES snes) 1966 { 1967 PetscErrorCode ierr; 1968 PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 1969 1970 PetscFunctionBegin; 1971 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1972 PetscValidHeaderSpecific(snes,SNES_CLASSID,2); 1973 ierr = PetscObjectReference((PetscObject)snes);CHKERRQ(ierr); 1974 ierr = SNESDestroy(&ts->snes);CHKERRQ(ierr); 1975 1976 ts->snes = snes; 1977 1978 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 1979 ierr = SNESGetJacobian(ts->snes,NULL,NULL,&func,NULL);CHKERRQ(ierr); 1980 if (func == SNESTSFormJacobian) { 1981 ierr = SNESSetJacobian(ts->snes,NULL,NULL,SNESTSFormJacobian,ts);CHKERRQ(ierr); 1982 } 1983 PetscFunctionReturn(0); 1984 } 1985 1986 #undef __FUNCT__ 1987 #define __FUNCT__ "TSGetKSP" 1988 /*@ 1989 TSGetKSP - Returns the KSP (linear solver) associated with 1990 a TS (timestepper) context. 1991 1992 Not Collective, but KSP is parallel if TS is parallel 1993 1994 Input Parameter: 1995 . ts - the TS context obtained from TSCreate() 1996 1997 Output Parameter: 1998 . ksp - the nonlinear solver context 1999 2000 Notes: 2001 The user can then directly manipulate the KSP context to set various 2002 options, etc. Likewise, the user can then extract and manipulate the 2003 KSP and PC contexts as well. 2004 2005 TSGetKSP() does not work for integrators that do not use KSP; 2006 in this case TSGetKSP() returns NULL in ksp. 2007 2008 Level: beginner 2009 2010 .keywords: timestep, get, KSP 2011 @*/ 2012 PetscErrorCode TSGetKSP(TS ts,KSP *ksp) 2013 { 2014 PetscErrorCode ierr; 2015 SNES snes; 2016 2017 PetscFunctionBegin; 2018 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2019 PetscValidPointer(ksp,2); 2020 if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first"); 2021 if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()"); 2022 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2023 ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr); 2024 PetscFunctionReturn(0); 2025 } 2026 2027 /* ----------- Routines to set solver parameters ---------- */ 2028 2029 #undef __FUNCT__ 2030 #define __FUNCT__ "TSGetDuration" 2031 /*@ 2032 TSGetDuration - Gets the maximum number of timesteps to use and 2033 maximum time for iteration. 2034 2035 Not Collective 2036 2037 Input Parameters: 2038 + ts - the TS context obtained from TSCreate() 2039 . maxsteps - maximum number of iterations to use, or NULL 2040 - maxtime - final time to iterate to, or NULL 2041 2042 Level: intermediate 2043 2044 .keywords: TS, timestep, get, maximum, iterations, time 2045 @*/ 2046 PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime) 2047 { 2048 PetscFunctionBegin; 2049 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2050 if (maxsteps) { 2051 PetscValidIntPointer(maxsteps,2); 2052 *maxsteps = ts->max_steps; 2053 } 2054 if (maxtime) { 2055 PetscValidScalarPointer(maxtime,3); 2056 *maxtime = ts->max_time; 2057 } 2058 PetscFunctionReturn(0); 2059 } 2060 2061 #undef __FUNCT__ 2062 #define __FUNCT__ "TSSetDuration" 2063 /*@ 2064 TSSetDuration - Sets the maximum number of timesteps to use and 2065 maximum time for iteration. 2066 2067 Logically Collective on TS 2068 2069 Input Parameters: 2070 + ts - the TS context obtained from TSCreate() 2071 . maxsteps - maximum number of iterations to use 2072 - maxtime - final time to iterate to 2073 2074 Options Database Keys: 2075 . -ts_max_steps <maxsteps> - Sets maxsteps 2076 . -ts_final_time <maxtime> - Sets maxtime 2077 2078 Notes: 2079 The default maximum number of iterations is 5000. Default time is 5.0 2080 2081 Level: intermediate 2082 2083 .keywords: TS, timestep, set, maximum, iterations 2084 2085 .seealso: TSSetExactFinalTime() 2086 @*/ 2087 PetscErrorCode TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime) 2088 { 2089 PetscFunctionBegin; 2090 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2091 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 2092 PetscValidLogicalCollectiveReal(ts,maxtime,2); 2093 if (maxsteps >= 0) ts->max_steps = maxsteps; 2094 if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime; 2095 PetscFunctionReturn(0); 2096 } 2097 2098 #undef __FUNCT__ 2099 #define __FUNCT__ "TSSetSolution" 2100 /*@ 2101 TSSetSolution - Sets the initial solution vector 2102 for use by the TS routines. 2103 2104 Logically Collective on TS and Vec 2105 2106 Input Parameters: 2107 + ts - the TS context obtained from TSCreate() 2108 - u - the solution vector 2109 2110 Level: beginner 2111 2112 .keywords: TS, timestep, set, solution, initial conditions 2113 @*/ 2114 PetscErrorCode TSSetSolution(TS ts,Vec u) 2115 { 2116 PetscErrorCode ierr; 2117 DM dm; 2118 2119 PetscFunctionBegin; 2120 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2121 PetscValidHeaderSpecific(u,VEC_CLASSID,2); 2122 ierr = PetscObjectReference((PetscObject)u);CHKERRQ(ierr); 2123 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 2124 2125 ts->vec_sol = u; 2126 2127 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 2128 ierr = DMShellSetGlobalVector(dm,u);CHKERRQ(ierr); 2129 PetscFunctionReturn(0); 2130 } 2131 2132 #undef __FUNCT__ 2133 #define __FUNCT__ "TSSetPreStep" 2134 /*@C 2135 TSSetPreStep - Sets the general-purpose function 2136 called once at the beginning of each time step. 2137 2138 Logically Collective on TS 2139 2140 Input Parameters: 2141 + ts - The TS context obtained from TSCreate() 2142 - func - The function 2143 2144 Calling sequence of func: 2145 . func (TS ts); 2146 2147 Level: intermediate 2148 2149 Note: 2150 If a step is rejected, TSStep() will call this routine again before each attempt. 2151 The last completed time step number can be queried using TSGetTimeStepNumber(), the 2152 size of the step being attempted can be obtained using TSGetTimeStep(). 2153 2154 .keywords: TS, timestep 2155 .seealso: TSSetPreStage(), TSSetPostStep(), TSStep() 2156 @*/ 2157 PetscErrorCode TSSetPreStep(TS ts, PetscErrorCode (*func)(TS)) 2158 { 2159 PetscFunctionBegin; 2160 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2161 ts->prestep = func; 2162 PetscFunctionReturn(0); 2163 } 2164 2165 #undef __FUNCT__ 2166 #define __FUNCT__ "TSPreStep" 2167 /*@ 2168 TSPreStep - Runs the user-defined pre-step function. 2169 2170 Collective on TS 2171 2172 Input Parameters: 2173 . ts - The TS context obtained from TSCreate() 2174 2175 Notes: 2176 TSPreStep() is typically used within time stepping implementations, 2177 so most users would not generally call this routine themselves. 2178 2179 Level: developer 2180 2181 .keywords: TS, timestep 2182 .seealso: TSSetPreStep(), TSPreStage(), TSPostStep() 2183 @*/ 2184 PetscErrorCode TSPreStep(TS ts) 2185 { 2186 PetscErrorCode ierr; 2187 2188 PetscFunctionBegin; 2189 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2190 if (ts->prestep) { 2191 PetscStackCallStandard((*ts->prestep),(ts)); 2192 } 2193 PetscFunctionReturn(0); 2194 } 2195 2196 #undef __FUNCT__ 2197 #define __FUNCT__ "TSSetPreStage" 2198 /*@C 2199 TSSetPreStage - Sets the general-purpose function 2200 called once at the beginning of each stage. 2201 2202 Logically Collective on TS 2203 2204 Input Parameters: 2205 + ts - The TS context obtained from TSCreate() 2206 - func - The function 2207 2208 Calling sequence of func: 2209 . PetscErrorCode func(TS ts, PetscReal stagetime); 2210 2211 Level: intermediate 2212 2213 Note: 2214 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 2215 The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being 2216 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 2217 2218 .keywords: TS, timestep 2219 .seealso: TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 2220 @*/ 2221 PetscErrorCode TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal)) 2222 { 2223 PetscFunctionBegin; 2224 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2225 ts->prestage = func; 2226 PetscFunctionReturn(0); 2227 } 2228 2229 #undef __FUNCT__ 2230 #define __FUNCT__ "TSPreStage" 2231 /*@ 2232 TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage() 2233 2234 Collective on TS 2235 2236 Input Parameters: 2237 . ts - The TS context obtained from TSCreate() 2238 2239 Notes: 2240 TSPreStage() is typically used within time stepping implementations, 2241 most users would not generally call this routine themselves. 2242 2243 Level: developer 2244 2245 .keywords: TS, timestep 2246 .seealso: TSSetPreStep(), TSPreStep(), TSPostStep() 2247 @*/ 2248 PetscErrorCode TSPreStage(TS ts, PetscReal stagetime) 2249 { 2250 PetscErrorCode ierr; 2251 2252 PetscFunctionBegin; 2253 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2254 if (ts->prestage) { 2255 PetscStackCallStandard((*ts->prestage),(ts,stagetime)); 2256 } 2257 PetscFunctionReturn(0); 2258 } 2259 2260 #undef __FUNCT__ 2261 #define __FUNCT__ "TSSetPostStep" 2262 /*@C 2263 TSSetPostStep - Sets the general-purpose function 2264 called once at the end of each time step. 2265 2266 Logically Collective on TS 2267 2268 Input Parameters: 2269 + ts - The TS context obtained from TSCreate() 2270 - func - The function 2271 2272 Calling sequence of func: 2273 $ func (TS ts); 2274 2275 Level: intermediate 2276 2277 .keywords: TS, timestep 2278 .seealso: TSSetPreStep(), TSSetPreStage(), TSGetTimeStep(), TSGetTimeStepNumber(), TSGetTime() 2279 @*/ 2280 PetscErrorCode TSSetPostStep(TS ts, PetscErrorCode (*func)(TS)) 2281 { 2282 PetscFunctionBegin; 2283 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2284 ts->poststep = func; 2285 PetscFunctionReturn(0); 2286 } 2287 2288 #undef __FUNCT__ 2289 #define __FUNCT__ "TSPostStep" 2290 /*@ 2291 TSPostStep - Runs the user-defined post-step function. 2292 2293 Collective on TS 2294 2295 Input Parameters: 2296 . ts - The TS context obtained from TSCreate() 2297 2298 Notes: 2299 TSPostStep() is typically used within time stepping implementations, 2300 so most users would not generally call this routine themselves. 2301 2302 Level: developer 2303 2304 .keywords: TS, timestep 2305 @*/ 2306 PetscErrorCode TSPostStep(TS ts) 2307 { 2308 PetscErrorCode ierr; 2309 2310 PetscFunctionBegin; 2311 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2312 if (ts->poststep) { 2313 PetscStackCallStandard((*ts->poststep),(ts)); 2314 } 2315 PetscFunctionReturn(0); 2316 } 2317 2318 /* ------------ Routines to set performance monitoring options ----------- */ 2319 2320 #undef __FUNCT__ 2321 #define __FUNCT__ "TSMonitorSet" 2322 /*@C 2323 TSMonitorSet - Sets an ADDITIONAL function that is to be used at every 2324 timestep to display the iteration's progress. 2325 2326 Logically Collective on TS 2327 2328 Input Parameters: 2329 + ts - the TS context obtained from TSCreate() 2330 . monitor - monitoring routine 2331 . mctx - [optional] user-defined context for private data for the 2332 monitor routine (use NULL if no context is desired) 2333 - monitordestroy - [optional] routine that frees monitor context 2334 (may be NULL) 2335 2336 Calling sequence of monitor: 2337 $ int monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx) 2338 2339 + ts - the TS context 2340 . steps - iteration number (after the final time step the monitor routine is called with a step of -1, this is at the final time which may have 2341 been interpolated to) 2342 . time - current time 2343 . u - current iterate 2344 - mctx - [optional] monitoring context 2345 2346 Notes: 2347 This routine adds an additional monitor to the list of monitors that 2348 already has been loaded. 2349 2350 Fortran notes: Only a single monitor function can be set for each TS object 2351 2352 Level: intermediate 2353 2354 .keywords: TS, timestep, set, monitor 2355 2356 .seealso: TSMonitorDefault(), TSMonitorCancel() 2357 @*/ 2358 PetscErrorCode TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**)) 2359 { 2360 PetscFunctionBegin; 2361 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2362 if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2363 ts->monitor[ts->numbermonitors] = monitor; 2364 ts->monitordestroy[ts->numbermonitors] = mdestroy; 2365 ts->monitorcontext[ts->numbermonitors++] = (void*)mctx; 2366 PetscFunctionReturn(0); 2367 } 2368 2369 #undef __FUNCT__ 2370 #define __FUNCT__ "TSMonitorCancel" 2371 /*@C 2372 TSMonitorCancel - Clears all the monitors that have been set on a time-step object. 2373 2374 Logically Collective on TS 2375 2376 Input Parameters: 2377 . ts - the TS context obtained from TSCreate() 2378 2379 Notes: 2380 There is no way to remove a single, specific monitor. 2381 2382 Level: intermediate 2383 2384 .keywords: TS, timestep, set, monitor 2385 2386 .seealso: TSMonitorDefault(), TSMonitorSet() 2387 @*/ 2388 PetscErrorCode TSMonitorCancel(TS ts) 2389 { 2390 PetscErrorCode ierr; 2391 PetscInt i; 2392 2393 PetscFunctionBegin; 2394 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2395 for (i=0; i<ts->numbermonitors; i++) { 2396 if (ts->monitordestroy[i]) { 2397 ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr); 2398 } 2399 } 2400 ts->numbermonitors = 0; 2401 PetscFunctionReturn(0); 2402 } 2403 2404 #undef __FUNCT__ 2405 #define __FUNCT__ "TSMonitorDefault" 2406 /*@ 2407 TSMonitorDefault - Sets the Default monitor 2408 2409 Level: intermediate 2410 2411 .keywords: TS, set, monitor 2412 2413 .seealso: TSMonitorDefault(), TSMonitorSet() 2414 @*/ 2415 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,void *dummy) 2416 { 2417 PetscErrorCode ierr; 2418 PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)ts)); 2419 2420 PetscFunctionBegin; 2421 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 2422 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g\n",step,(double)ts->time_step,(double)ptime);CHKERRQ(ierr); 2423 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 2424 PetscFunctionReturn(0); 2425 } 2426 2427 #undef __FUNCT__ 2428 #define __FUNCT__ "TSSetRetainStages" 2429 /*@ 2430 TSSetRetainStages - Request that all stages in the upcoming step be stored so that interpolation will be available. 2431 2432 Logically Collective on TS 2433 2434 Input Argument: 2435 . ts - time stepping context 2436 2437 Output Argument: 2438 . flg - PETSC_TRUE or PETSC_FALSE 2439 2440 Level: intermediate 2441 2442 .keywords: TS, set 2443 2444 .seealso: TSInterpolate(), TSSetPostStep() 2445 @*/ 2446 PetscErrorCode TSSetRetainStages(TS ts,PetscBool flg) 2447 { 2448 PetscFunctionBegin; 2449 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2450 ts->retain_stages = flg; 2451 PetscFunctionReturn(0); 2452 } 2453 2454 #undef __FUNCT__ 2455 #define __FUNCT__ "TSInterpolate" 2456 /*@ 2457 TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval 2458 2459 Collective on TS 2460 2461 Input Argument: 2462 + ts - time stepping context 2463 - t - time to interpolate to 2464 2465 Output Argument: 2466 . U - state at given time 2467 2468 Notes: 2469 The user should call TSSetRetainStages() before taking a step in which interpolation will be requested. 2470 2471 Level: intermediate 2472 2473 Developer Notes: 2474 TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints. 2475 2476 .keywords: TS, set 2477 2478 .seealso: TSSetRetainStages(), TSSetPostStep() 2479 @*/ 2480 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U) 2481 { 2482 PetscErrorCode ierr; 2483 2484 PetscFunctionBegin; 2485 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2486 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 2487 if (t < ts->ptime - ts->time_step_prev || t > ts->ptime) SETERRQ3(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Requested time %G not in last time steps [%G,%G]",t,ts->ptime-ts->time_step_prev,ts->ptime); 2488 if (!ts->ops->interpolate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name); 2489 ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr); 2490 PetscFunctionReturn(0); 2491 } 2492 2493 #undef __FUNCT__ 2494 #define __FUNCT__ "TSStep" 2495 /*@ 2496 TSStep - Steps one time step 2497 2498 Collective on TS 2499 2500 Input Parameter: 2501 . ts - the TS context obtained from TSCreate() 2502 2503 Level: intermediate 2504 2505 Notes: 2506 The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may 2507 be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages. 2508 2509 This may over-step the final time provided in TSSetDuration() depending on the time-step used. TSSolve() interpolates to exactly the 2510 time provided in TSSetDuration(). One can use TSInterpolate() to determine an interpolated solution within the final timestep. 2511 2512 .keywords: TS, timestep, solve 2513 2514 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate() 2515 @*/ 2516 PetscErrorCode TSStep(TS ts) 2517 { 2518 PetscReal ptime_prev; 2519 PetscErrorCode ierr; 2520 2521 PetscFunctionBegin; 2522 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2523 ierr = TSSetUp(ts);CHKERRQ(ierr); 2524 2525 ts->reason = TS_CONVERGED_ITERATING; 2526 ptime_prev = ts->ptime; 2527 2528 ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr); 2529 ierr = (*ts->ops->step)(ts);CHKERRQ(ierr); 2530 ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr); 2531 2532 ts->time_step_prev = ts->ptime - ptime_prev; 2533 2534 if (ts->reason < 0) { 2535 if (ts->errorifstepfailed) { 2536 if (ts->reason == TS_DIVERGED_NONLINEAR_SOLVE) { 2537 SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s, increase -ts_max_snes_failures or make negative to attempt recovery",TSConvergedReasons[ts->reason]); 2538 } else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]); 2539 } 2540 } else if (!ts->reason) { 2541 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 2542 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 2543 } 2544 PetscFunctionReturn(0); 2545 } 2546 2547 #undef __FUNCT__ 2548 #define __FUNCT__ "TSEvaluateStep" 2549 /*@ 2550 TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy. 2551 2552 Collective on TS 2553 2554 Input Arguments: 2555 + ts - time stepping context 2556 . order - desired order of accuracy 2557 - done - whether the step was evaluated at this order (pass NULL to generate an error if not available) 2558 2559 Output Arguments: 2560 . U - state at the end of the current step 2561 2562 Level: advanced 2563 2564 Notes: 2565 This function cannot be called until all stages have been evaluated. 2566 It is normally called by adaptive controllers before a step has been accepted and may also be called by the user after TSStep() has returned. 2567 2568 .seealso: TSStep(), TSAdapt 2569 @*/ 2570 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done) 2571 { 2572 PetscErrorCode ierr; 2573 2574 PetscFunctionBegin; 2575 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2576 PetscValidType(ts,1); 2577 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 2578 if (!ts->ops->evaluatestep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name); 2579 ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr); 2580 PetscFunctionReturn(0); 2581 } 2582 2583 #undef __FUNCT__ 2584 #define __FUNCT__ "TSSolve" 2585 /*@ 2586 TSSolve - Steps the requested number of timesteps. 2587 2588 Collective on TS 2589 2590 Input Parameter: 2591 + ts - the TS context obtained from TSCreate() 2592 - u - the solution vector (can be null if TSSetSolution() was used, otherwise must contain the initial conditions) 2593 2594 Level: beginner 2595 2596 Notes: 2597 The final time returned by this function may be different from the time of the internally 2598 held state accessible by TSGetSolution() and TSGetTime() because the method may have 2599 stepped over the final time. 2600 2601 .keywords: TS, timestep, solve 2602 2603 .seealso: TSCreate(), TSSetSolution(), TSStep() 2604 @*/ 2605 PetscErrorCode TSSolve(TS ts,Vec u) 2606 { 2607 PetscBool flg; 2608 PetscViewer viewer; 2609 Vec solution; 2610 PetscErrorCode ierr; 2611 PetscViewerFormat format; 2612 2613 PetscFunctionBegin; 2614 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2615 if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2); 2616 if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE) { /* Need ts->vec_sol to be distinct so it is not overwritten when we interpolate at the end */ 2617 PetscValidHeaderSpecific(u,VEC_CLASSID,2); 2618 if (!ts->vec_sol || u == ts->vec_sol) { 2619 ierr = VecDuplicate(u,&solution);CHKERRQ(ierr); 2620 ierr = TSSetSolution(ts,solution);CHKERRQ(ierr); 2621 ierr = VecDestroy(&solution);CHKERRQ(ierr); /* grant ownership */ 2622 } 2623 ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr); 2624 } else if (u) { 2625 ierr = TSSetSolution(ts,u);CHKERRQ(ierr); 2626 } 2627 ierr = TSSetUp(ts);CHKERRQ(ierr); 2628 /* reset time step and iteration counters */ 2629 ts->steps = 0; 2630 ts->ksp_its = 0; 2631 ts->snes_its = 0; 2632 ts->num_snes_failures = 0; 2633 ts->reject = 0; 2634 ts->reason = TS_CONVERGED_ITERATING; 2635 2636 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts),((PetscObject)ts)->prefix,"-ts_view_pre",&viewer,&format,&flg);CHKERRQ(ierr); 2637 if (flg && !PetscPreLoadingOn) { 2638 ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 2639 ierr = TSView(ts,viewer);CHKERRQ(ierr); 2640 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 2641 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 2642 } 2643 2644 if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */ 2645 ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr); 2646 ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr); 2647 ts->solvetime = ts->ptime; 2648 } else { 2649 /* steps the requested number of timesteps. */ 2650 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 2651 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 2652 while (!ts->reason) { 2653 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 2654 ierr = TSStep(ts);CHKERRQ(ierr); 2655 ierr = TSPostStep(ts);CHKERRQ(ierr); 2656 } 2657 if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) { 2658 ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr); 2659 ts->solvetime = ts->max_time; 2660 solution = u; 2661 } else { 2662 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 2663 ts->solvetime = ts->ptime; 2664 solution = ts->vec_sol; 2665 } 2666 ierr = TSMonitor(ts,ts->steps,ts->solvetime,solution);CHKERRQ(ierr); 2667 } 2668 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts),((PetscObject)ts)->prefix,"-ts_view",&viewer,&format,&flg);CHKERRQ(ierr); 2669 if (flg && !PetscPreLoadingOn) { 2670 ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 2671 ierr = TSView(ts,viewer);CHKERRQ(ierr); 2672 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 2673 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 2674 } 2675 ierr = PetscObjectSAWsBlock((PetscObject)ts);CHKERRQ(ierr); 2676 PetscFunctionReturn(0); 2677 } 2678 2679 #undef __FUNCT__ 2680 #define __FUNCT__ "TSMonitor" 2681 /*@ 2682 TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet() 2683 2684 Collective on TS 2685 2686 Input Parameters: 2687 + ts - time stepping context obtained from TSCreate() 2688 . step - step number that has just completed 2689 . ptime - model time of the state 2690 - u - state at the current model time 2691 2692 Notes: 2693 TSMonitor() is typically used within the time stepping implementations. 2694 Users might call this function when using the TSStep() interface instead of TSSolve(). 2695 2696 Level: advanced 2697 2698 .keywords: TS, timestep 2699 @*/ 2700 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u) 2701 { 2702 PetscErrorCode ierr; 2703 PetscInt i,n = ts->numbermonitors; 2704 2705 PetscFunctionBegin; 2706 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2707 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 2708 for (i=0; i<n; i++) { 2709 ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr); 2710 } 2711 PetscFunctionReturn(0); 2712 } 2713 2714 /* ------------------------------------------------------------------------*/ 2715 struct _n_TSMonitorLGCtx { 2716 PetscDrawLG lg; 2717 PetscInt howoften; /* when > 0 uses step % howoften, when negative only final solution plotted */ 2718 PetscInt ksp_its,snes_its; 2719 }; 2720 2721 2722 #undef __FUNCT__ 2723 #define __FUNCT__ "TSMonitorLGCtxCreate" 2724 /*@C 2725 TSMonitorLGCtxCreate - Creates a line graph context for use with 2726 TS to monitor the solution process graphically in various ways 2727 2728 Collective on TS 2729 2730 Input Parameters: 2731 + host - the X display to open, or null for the local machine 2732 . label - the title to put in the title bar 2733 . x, y - the screen coordinates of the upper left coordinate of the window 2734 . m, n - the screen width and height in pixels 2735 - howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time 2736 2737 Output Parameter: 2738 . ctx - the context 2739 2740 Options Database Key: 2741 + -ts_monitor_lg_timestep - automatically sets line graph monitor 2742 . -ts_monitor_lg_solution - 2743 . -ts_monitor_lg_error - 2744 . -ts_monitor_lg_ksp_iterations - 2745 . -ts_monitor_lg_snes_iterations - 2746 - -lg_indicate_data_points <true,false> - indicate the data points (at each time step) on the plot; default is true 2747 2748 Notes: 2749 Use TSMonitorLGCtxDestroy() to destroy. 2750 2751 Level: intermediate 2752 2753 .keywords: TS, monitor, line graph, residual, seealso 2754 2755 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError() 2756 2757 @*/ 2758 PetscErrorCode TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx) 2759 { 2760 PetscDraw win; 2761 PetscErrorCode ierr; 2762 PetscBool flg = PETSC_TRUE; 2763 2764 PetscFunctionBegin; 2765 ierr = PetscNew(struct _n_TSMonitorLGCtx,ctx);CHKERRQ(ierr); 2766 ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&win);CHKERRQ(ierr); 2767 ierr = PetscDrawSetFromOptions(win);CHKERRQ(ierr); 2768 ierr = PetscDrawLGCreate(win,1,&(*ctx)->lg);CHKERRQ(ierr); 2769 ierr = PetscOptionsGetBool(NULL,"-lg_indicate_data_points",&flg,NULL);CHKERRQ(ierr); 2770 if (flg) { 2771 ierr = PetscDrawLGIndicateDataPoints((*ctx)->lg);CHKERRQ(ierr); 2772 } 2773 ierr = PetscLogObjectParent((PetscObject)(*ctx)->lg,(PetscObject)win);CHKERRQ(ierr); 2774 (*ctx)->howoften = howoften; 2775 PetscFunctionReturn(0); 2776 } 2777 2778 #undef __FUNCT__ 2779 #define __FUNCT__ "TSMonitorLGTimeStep" 2780 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx) 2781 { 2782 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 2783 PetscReal x = ptime,y; 2784 PetscErrorCode ierr; 2785 2786 PetscFunctionBegin; 2787 if (!step) { 2788 PetscDrawAxis axis; 2789 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 2790 ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time","Time step");CHKERRQ(ierr); 2791 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 2792 } 2793 ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr); 2794 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 2795 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 2796 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 2797 } 2798 PetscFunctionReturn(0); 2799 } 2800 2801 #undef __FUNCT__ 2802 #define __FUNCT__ "TSMonitorLGCtxDestroy" 2803 /*@C 2804 TSMonitorLGCtxDestroy - Destroys a line graph context that was created 2805 with TSMonitorLGCtxCreate(). 2806 2807 Collective on TSMonitorLGCtx 2808 2809 Input Parameter: 2810 . ctx - the monitor context 2811 2812 Level: intermediate 2813 2814 .keywords: TS, monitor, line graph, destroy 2815 2816 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep(); 2817 @*/ 2818 PetscErrorCode TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx) 2819 { 2820 PetscDraw draw; 2821 PetscErrorCode ierr; 2822 2823 PetscFunctionBegin; 2824 ierr = PetscDrawLGGetDraw((*ctx)->lg,&draw);CHKERRQ(ierr); 2825 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 2826 ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr); 2827 ierr = PetscFree(*ctx);CHKERRQ(ierr); 2828 PetscFunctionReturn(0); 2829 } 2830 2831 #undef __FUNCT__ 2832 #define __FUNCT__ "TSGetTime" 2833 /*@ 2834 TSGetTime - Gets the time of the most recently completed step. 2835 2836 Not Collective 2837 2838 Input Parameter: 2839 . ts - the TS context obtained from TSCreate() 2840 2841 Output Parameter: 2842 . t - the current time 2843 2844 Level: beginner 2845 2846 Note: 2847 When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(), 2848 TSSetPreStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated. 2849 2850 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 2851 2852 .keywords: TS, get, time 2853 @*/ 2854 PetscErrorCode TSGetTime(TS ts,PetscReal *t) 2855 { 2856 PetscFunctionBegin; 2857 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2858 PetscValidRealPointer(t,2); 2859 *t = ts->ptime; 2860 PetscFunctionReturn(0); 2861 } 2862 2863 #undef __FUNCT__ 2864 #define __FUNCT__ "TSSetTime" 2865 /*@ 2866 TSSetTime - Allows one to reset the time. 2867 2868 Logically Collective on TS 2869 2870 Input Parameters: 2871 + ts - the TS context obtained from TSCreate() 2872 - time - the time 2873 2874 Level: intermediate 2875 2876 .seealso: TSGetTime(), TSSetDuration() 2877 2878 .keywords: TS, set, time 2879 @*/ 2880 PetscErrorCode TSSetTime(TS ts, PetscReal t) 2881 { 2882 PetscFunctionBegin; 2883 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2884 PetscValidLogicalCollectiveReal(ts,t,2); 2885 ts->ptime = t; 2886 PetscFunctionReturn(0); 2887 } 2888 2889 #undef __FUNCT__ 2890 #define __FUNCT__ "TSSetOptionsPrefix" 2891 /*@C 2892 TSSetOptionsPrefix - Sets the prefix used for searching for all 2893 TS options in the database. 2894 2895 Logically Collective on TS 2896 2897 Input Parameter: 2898 + ts - The TS context 2899 - prefix - The prefix to prepend to all option names 2900 2901 Notes: 2902 A hyphen (-) must NOT be given at the beginning of the prefix name. 2903 The first character of all runtime options is AUTOMATICALLY the 2904 hyphen. 2905 2906 Level: advanced 2907 2908 .keywords: TS, set, options, prefix, database 2909 2910 .seealso: TSSetFromOptions() 2911 2912 @*/ 2913 PetscErrorCode TSSetOptionsPrefix(TS ts,const char prefix[]) 2914 { 2915 PetscErrorCode ierr; 2916 SNES snes; 2917 2918 PetscFunctionBegin; 2919 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2920 ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 2921 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2922 ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr); 2923 PetscFunctionReturn(0); 2924 } 2925 2926 2927 #undef __FUNCT__ 2928 #define __FUNCT__ "TSAppendOptionsPrefix" 2929 /*@C 2930 TSAppendOptionsPrefix - Appends to the prefix used for searching for all 2931 TS options in the database. 2932 2933 Logically Collective on TS 2934 2935 Input Parameter: 2936 + ts - The TS context 2937 - prefix - The prefix to prepend to all option names 2938 2939 Notes: 2940 A hyphen (-) must NOT be given at the beginning of the prefix name. 2941 The first character of all runtime options is AUTOMATICALLY the 2942 hyphen. 2943 2944 Level: advanced 2945 2946 .keywords: TS, append, options, prefix, database 2947 2948 .seealso: TSGetOptionsPrefix() 2949 2950 @*/ 2951 PetscErrorCode TSAppendOptionsPrefix(TS ts,const char prefix[]) 2952 { 2953 PetscErrorCode ierr; 2954 SNES snes; 2955 2956 PetscFunctionBegin; 2957 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2958 ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 2959 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2960 ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr); 2961 PetscFunctionReturn(0); 2962 } 2963 2964 #undef __FUNCT__ 2965 #define __FUNCT__ "TSGetOptionsPrefix" 2966 /*@C 2967 TSGetOptionsPrefix - Sets the prefix used for searching for all 2968 TS options in the database. 2969 2970 Not Collective 2971 2972 Input Parameter: 2973 . ts - The TS context 2974 2975 Output Parameter: 2976 . prefix - A pointer to the prefix string used 2977 2978 Notes: On the fortran side, the user should pass in a string 'prifix' of 2979 sufficient length to hold the prefix. 2980 2981 Level: intermediate 2982 2983 .keywords: TS, get, options, prefix, database 2984 2985 .seealso: TSAppendOptionsPrefix() 2986 @*/ 2987 PetscErrorCode TSGetOptionsPrefix(TS ts,const char *prefix[]) 2988 { 2989 PetscErrorCode ierr; 2990 2991 PetscFunctionBegin; 2992 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2993 PetscValidPointer(prefix,2); 2994 ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 2995 PetscFunctionReturn(0); 2996 } 2997 2998 #undef __FUNCT__ 2999 #define __FUNCT__ "TSGetRHSJacobian" 3000 /*@C 3001 TSGetRHSJacobian - Returns the Jacobian J at the present timestep. 3002 3003 Not Collective, but parallel objects are returned if TS is parallel 3004 3005 Input Parameter: 3006 . ts - The TS context obtained from TSCreate() 3007 3008 Output Parameters: 3009 + Amat - The (approximate) Jacobian J of G, where U_t = G(U,t) (or NULL) 3010 . Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat (or NULL) 3011 . func - Function to compute the Jacobian of the RHS (or NULL) 3012 - ctx - User-defined context for Jacobian evaluation routine (or NULL) 3013 3014 Notes: You can pass in NULL for any return argument you do not need. 3015 3016 Level: intermediate 3017 3018 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 3019 3020 .keywords: TS, timestep, get, matrix, Jacobian 3021 @*/ 3022 PetscErrorCode TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx) 3023 { 3024 PetscErrorCode ierr; 3025 SNES snes; 3026 DM dm; 3027 3028 PetscFunctionBegin; 3029 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 3030 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 3031 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 3032 ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr); 3033 PetscFunctionReturn(0); 3034 } 3035 3036 #undef __FUNCT__ 3037 #define __FUNCT__ "TSGetIJacobian" 3038 /*@C 3039 TSGetIJacobian - Returns the implicit Jacobian at the present timestep. 3040 3041 Not Collective, but parallel objects are returned if TS is parallel 3042 3043 Input Parameter: 3044 . ts - The TS context obtained from TSCreate() 3045 3046 Output Parameters: 3047 + Amat - The (approximate) Jacobian of F(t,U,U_t) 3048 . Pmat - The matrix from which the preconditioner is constructed, often the same as Amat 3049 . f - The function to compute the matrices 3050 - ctx - User-defined context for Jacobian evaluation routine 3051 3052 Notes: You can pass in NULL for any return argument you do not need. 3053 3054 Level: advanced 3055 3056 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 3057 3058 .keywords: TS, timestep, get, matrix, Jacobian 3059 @*/ 3060 PetscErrorCode TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx) 3061 { 3062 PetscErrorCode ierr; 3063 SNES snes; 3064 DM dm; 3065 3066 PetscFunctionBegin; 3067 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 3068 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 3069 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 3070 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 3071 ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr); 3072 PetscFunctionReturn(0); 3073 } 3074 3075 3076 #undef __FUNCT__ 3077 #define __FUNCT__ "TSMonitorDrawSolution" 3078 /*@C 3079 TSMonitorDrawSolution - Monitors progress of the TS solvers by calling 3080 VecView() for the solution at each timestep 3081 3082 Collective on TS 3083 3084 Input Parameters: 3085 + ts - the TS context 3086 . step - current time-step 3087 . ptime - current time 3088 - dummy - either a viewer or NULL 3089 3090 Options Database: 3091 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 3092 3093 Notes: the initial solution and current solution are not displayed with a common axis scaling so generally the option -ts_monitor_draw_solution_initial 3094 will look bad 3095 3096 Level: intermediate 3097 3098 .keywords: TS, vector, monitor, view 3099 3100 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 3101 @*/ 3102 PetscErrorCode TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 3103 { 3104 PetscErrorCode ierr; 3105 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 3106 PetscDraw draw; 3107 3108 PetscFunctionBegin; 3109 if (!step && ictx->showinitial) { 3110 if (!ictx->initialsolution) { 3111 ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr); 3112 } 3113 ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr); 3114 } 3115 if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 3116 3117 if (ictx->showinitial) { 3118 PetscReal pause; 3119 ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr); 3120 ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr); 3121 ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr); 3122 ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr); 3123 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr); 3124 } 3125 ierr = VecView(u,ictx->viewer);CHKERRQ(ierr); 3126 if (ictx->showtimestepandtime) { 3127 PetscReal xl,yl,xr,yr,tw,w,h; 3128 char time[32]; 3129 size_t len; 3130 3131 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 3132 ierr = PetscSNPrintf(time,32,"Timestep %d Time %f",(int)step,(double)ptime);CHKERRQ(ierr); 3133 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 3134 ierr = PetscStrlen(time,&len);CHKERRQ(ierr); 3135 ierr = PetscDrawStringGetSize(draw,&tw,NULL);CHKERRQ(ierr); 3136 w = xl + .5*(xr - xl) - .5*len*tw; 3137 h = yl + .95*(yr - yl); 3138 ierr = PetscDrawString(draw,w,h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 3139 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 3140 } 3141 3142 if (ictx->showinitial) { 3143 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr); 3144 } 3145 PetscFunctionReturn(0); 3146 } 3147 3148 #undef __FUNCT__ 3149 #define __FUNCT__ "TSMonitorDrawSolutionPhase" 3150 /*@C 3151 TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram 3152 3153 Collective on TS 3154 3155 Input Parameters: 3156 + ts - the TS context 3157 . step - current time-step 3158 . ptime - current time 3159 - dummy - either a viewer or NULL 3160 3161 Level: intermediate 3162 3163 .keywords: TS, vector, monitor, view 3164 3165 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 3166 @*/ 3167 PetscErrorCode TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 3168 { 3169 PetscErrorCode ierr; 3170 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 3171 PetscDraw draw; 3172 MPI_Comm comm; 3173 PetscInt n; 3174 PetscMPIInt size; 3175 PetscReal xl,yl,xr,yr,tw,w,h; 3176 char time[32]; 3177 size_t len; 3178 const PetscScalar *U; 3179 3180 PetscFunctionBegin; 3181 ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr); 3182 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 3183 if (size != 1) SETERRQ(comm,PETSC_ERR_SUP,"Only allowed for sequential runs"); 3184 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 3185 if (n != 2) SETERRQ(comm,PETSC_ERR_SUP,"Only for ODEs with two unknowns"); 3186 3187 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 3188 3189 ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr); 3190 ierr = PetscDrawAxisGetLimits(ictx->axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr); 3191 if ((PetscRealPart(U[0]) < xl) || (PetscRealPart(U[1]) < yl) || (PetscRealPart(U[0]) > xr) || (PetscRealPart(U[1]) > yr)) { 3192 ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr); 3193 PetscFunctionReturn(0); 3194 } 3195 if (!step) ictx->color++; 3196 ierr = PetscDrawPoint(draw,PetscRealPart(U[0]),PetscRealPart(U[1]),ictx->color);CHKERRQ(ierr); 3197 ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr); 3198 3199 if (ictx->showtimestepandtime) { 3200 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 3201 ierr = PetscSNPrintf(time,32,"Timestep %d Time %f",(int)step,(double)ptime);CHKERRQ(ierr); 3202 ierr = PetscStrlen(time,&len);CHKERRQ(ierr); 3203 ierr = PetscDrawStringGetSize(draw,&tw,NULL);CHKERRQ(ierr); 3204 w = xl + .5*(xr - xl) - .5*len*tw; 3205 h = yl + .95*(yr - yl); 3206 ierr = PetscDrawString(draw,w,h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 3207 } 3208 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 3209 PetscFunctionReturn(0); 3210 } 3211 3212 3213 #undef __FUNCT__ 3214 #define __FUNCT__ "TSMonitorDrawCtxDestroy" 3215 /*@C 3216 TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution() 3217 3218 Collective on TS 3219 3220 Input Parameters: 3221 . ctx - the monitor context 3222 3223 Level: intermediate 3224 3225 .keywords: TS, vector, monitor, view 3226 3227 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError() 3228 @*/ 3229 PetscErrorCode TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx) 3230 { 3231 PetscErrorCode ierr; 3232 3233 PetscFunctionBegin; 3234 ierr = PetscDrawAxisDestroy(&(*ictx)->axis);CHKERRQ(ierr); 3235 ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr); 3236 ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr); 3237 ierr = PetscFree(*ictx);CHKERRQ(ierr); 3238 PetscFunctionReturn(0); 3239 } 3240 3241 #undef __FUNCT__ 3242 #define __FUNCT__ "TSMonitorDrawCtxCreate" 3243 /*@C 3244 TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx 3245 3246 Collective on TS 3247 3248 Input Parameter: 3249 . ts - time-step context 3250 3251 Output Patameter: 3252 . ctx - the monitor context 3253 3254 Options Database: 3255 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 3256 3257 Level: intermediate 3258 3259 .keywords: TS, vector, monitor, view 3260 3261 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx() 3262 @*/ 3263 PetscErrorCode TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx) 3264 { 3265 PetscErrorCode ierr; 3266 3267 PetscFunctionBegin; 3268 ierr = PetscNew(struct _n_TSMonitorDrawCtx,ctx);CHKERRQ(ierr); 3269 ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr); 3270 ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr); 3271 3272 (*ctx)->howoften = howoften; 3273 (*ctx)->showinitial = PETSC_FALSE; 3274 ierr = PetscOptionsGetBool(NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr); 3275 3276 (*ctx)->showtimestepandtime = PETSC_FALSE; 3277 ierr = PetscOptionsGetBool(NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr); 3278 (*ctx)->color = PETSC_DRAW_WHITE; 3279 PetscFunctionReturn(0); 3280 } 3281 3282 #undef __FUNCT__ 3283 #define __FUNCT__ "TSMonitorDrawError" 3284 /*@C 3285 TSMonitorDrawError - Monitors progress of the TS solvers by calling 3286 VecView() for the error at each timestep 3287 3288 Collective on TS 3289 3290 Input Parameters: 3291 + ts - the TS context 3292 . step - current time-step 3293 . ptime - current time 3294 - dummy - either a viewer or NULL 3295 3296 Level: intermediate 3297 3298 .keywords: TS, vector, monitor, view 3299 3300 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 3301 @*/ 3302 PetscErrorCode TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 3303 { 3304 PetscErrorCode ierr; 3305 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 3306 PetscViewer viewer = ctx->viewer; 3307 Vec work; 3308 3309 PetscFunctionBegin; 3310 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 3311 ierr = VecDuplicate(u,&work);CHKERRQ(ierr); 3312 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 3313 ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr); 3314 ierr = VecView(work,viewer);CHKERRQ(ierr); 3315 ierr = VecDestroy(&work);CHKERRQ(ierr); 3316 PetscFunctionReturn(0); 3317 } 3318 3319 #include <petsc-private/dmimpl.h> 3320 #undef __FUNCT__ 3321 #define __FUNCT__ "TSSetDM" 3322 /*@ 3323 TSSetDM - Sets the DM that may be used by some preconditioners 3324 3325 Logically Collective on TS and DM 3326 3327 Input Parameters: 3328 + ts - the preconditioner context 3329 - dm - the dm 3330 3331 Level: intermediate 3332 3333 3334 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM() 3335 @*/ 3336 PetscErrorCode TSSetDM(TS ts,DM dm) 3337 { 3338 PetscErrorCode ierr; 3339 SNES snes; 3340 DMTS tsdm; 3341 3342 PetscFunctionBegin; 3343 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3344 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 3345 if (ts->dm) { /* Move the DMTS context over to the new DM unless the new DM already has one */ 3346 if (ts->dm->dmts && !dm->dmts) { 3347 ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr); 3348 ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr); 3349 if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */ 3350 tsdm->originaldm = dm; 3351 } 3352 } 3353 ierr = DMDestroy(&ts->dm);CHKERRQ(ierr); 3354 } 3355 ts->dm = dm; 3356 3357 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 3358 ierr = SNESSetDM(snes,dm);CHKERRQ(ierr); 3359 PetscFunctionReturn(0); 3360 } 3361 3362 #undef __FUNCT__ 3363 #define __FUNCT__ "TSGetDM" 3364 /*@ 3365 TSGetDM - Gets the DM that may be used by some preconditioners 3366 3367 Not Collective 3368 3369 Input Parameter: 3370 . ts - the preconditioner context 3371 3372 Output Parameter: 3373 . dm - the dm 3374 3375 Level: intermediate 3376 3377 3378 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM() 3379 @*/ 3380 PetscErrorCode TSGetDM(TS ts,DM *dm) 3381 { 3382 PetscErrorCode ierr; 3383 3384 PetscFunctionBegin; 3385 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3386 if (!ts->dm) { 3387 ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr); 3388 if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 3389 } 3390 *dm = ts->dm; 3391 PetscFunctionReturn(0); 3392 } 3393 3394 #undef __FUNCT__ 3395 #define __FUNCT__ "SNESTSFormFunction" 3396 /*@ 3397 SNESTSFormFunction - Function to evaluate nonlinear residual 3398 3399 Logically Collective on SNES 3400 3401 Input Parameter: 3402 + snes - nonlinear solver 3403 . U - the current state at which to evaluate the residual 3404 - ctx - user context, must be a TS 3405 3406 Output Parameter: 3407 . F - the nonlinear residual 3408 3409 Notes: 3410 This function is not normally called by users and is automatically registered with the SNES used by TS. 3411 It is most frequently passed to MatFDColoringSetFunction(). 3412 3413 Level: advanced 3414 3415 .seealso: SNESSetFunction(), MatFDColoringSetFunction() 3416 @*/ 3417 PetscErrorCode SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx) 3418 { 3419 TS ts = (TS)ctx; 3420 PetscErrorCode ierr; 3421 3422 PetscFunctionBegin; 3423 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3424 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 3425 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 3426 PetscValidHeaderSpecific(ts,TS_CLASSID,4); 3427 ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr); 3428 PetscFunctionReturn(0); 3429 } 3430 3431 #undef __FUNCT__ 3432 #define __FUNCT__ "SNESTSFormJacobian" 3433 /*@ 3434 SNESTSFormJacobian - Function to evaluate the Jacobian 3435 3436 Collective on SNES 3437 3438 Input Parameter: 3439 + snes - nonlinear solver 3440 . U - the current state at which to evaluate the residual 3441 - ctx - user context, must be a TS 3442 3443 Output Parameter: 3444 + A - the Jacobian 3445 . B - the preconditioning matrix (may be the same as A) 3446 - flag - indicates any structure change in the matrix 3447 3448 Notes: 3449 This function is not normally called by users and is automatically registered with the SNES used by TS. 3450 3451 Level: developer 3452 3453 .seealso: SNESSetJacobian() 3454 @*/ 3455 PetscErrorCode SNESTSFormJacobian(SNES snes,Vec U,Mat *A,Mat *B,MatStructure *flag,void *ctx) 3456 { 3457 TS ts = (TS)ctx; 3458 PetscErrorCode ierr; 3459 3460 PetscFunctionBegin; 3461 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3462 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 3463 PetscValidPointer(A,3); 3464 PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 3465 PetscValidPointer(B,4); 3466 PetscValidHeaderSpecific(*B,MAT_CLASSID,4); 3467 PetscValidPointer(flag,5); 3468 PetscValidHeaderSpecific(ts,TS_CLASSID,6); 3469 ierr = (ts->ops->snesjacobian)(snes,U,A,B,flag,ts);CHKERRQ(ierr); 3470 PetscFunctionReturn(0); 3471 } 3472 3473 #undef __FUNCT__ 3474 #define __FUNCT__ "TSComputeRHSFunctionLinear" 3475 /*@C 3476 TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems only 3477 3478 Collective on TS 3479 3480 Input Arguments: 3481 + ts - time stepping context 3482 . t - time at which to evaluate 3483 . U - state at which to evaluate 3484 - ctx - context 3485 3486 Output Arguments: 3487 . F - right hand side 3488 3489 Level: intermediate 3490 3491 Notes: 3492 This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems. 3493 The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian(). 3494 3495 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 3496 @*/ 3497 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx) 3498 { 3499 PetscErrorCode ierr; 3500 Mat Arhs,Brhs; 3501 MatStructure flg2; 3502 3503 PetscFunctionBegin; 3504 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 3505 ierr = TSComputeRHSJacobian(ts,t,U,&Arhs,&Brhs,&flg2);CHKERRQ(ierr); 3506 ierr = MatMult(Arhs,U,F);CHKERRQ(ierr); 3507 PetscFunctionReturn(0); 3508 } 3509 3510 #undef __FUNCT__ 3511 #define __FUNCT__ "TSComputeRHSJacobianConstant" 3512 /*@C 3513 TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent. 3514 3515 Collective on TS 3516 3517 Input Arguments: 3518 + ts - time stepping context 3519 . t - time at which to evaluate 3520 . U - state at which to evaluate 3521 - ctx - context 3522 3523 Output Arguments: 3524 + A - pointer to operator 3525 . B - pointer to preconditioning matrix 3526 - flg - matrix structure flag 3527 3528 Level: intermediate 3529 3530 Notes: 3531 This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems. 3532 3533 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear() 3534 @*/ 3535 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat *A,Mat *B,MatStructure *flg,void *ctx) 3536 { 3537 PetscFunctionBegin; 3538 *flg = SAME_PRECONDITIONER; 3539 PetscFunctionReturn(0); 3540 } 3541 3542 #undef __FUNCT__ 3543 #define __FUNCT__ "TSComputeIFunctionLinear" 3544 /*@C 3545 TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only 3546 3547 Collective on TS 3548 3549 Input Arguments: 3550 + ts - time stepping context 3551 . t - time at which to evaluate 3552 . U - state at which to evaluate 3553 . Udot - time derivative of state vector 3554 - ctx - context 3555 3556 Output Arguments: 3557 . F - left hand side 3558 3559 Level: intermediate 3560 3561 Notes: 3562 The assumption here is that the left hand side is of the form A*Udot (and not A*Udot + B*U). For other cases, the 3563 user is required to write their own TSComputeIFunction. 3564 This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems. 3565 The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian(). 3566 3567 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant() 3568 @*/ 3569 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx) 3570 { 3571 PetscErrorCode ierr; 3572 Mat A,B; 3573 MatStructure flg2; 3574 3575 PetscFunctionBegin; 3576 ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr); 3577 ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,&A,&B,&flg2,PETSC_TRUE);CHKERRQ(ierr); 3578 ierr = MatMult(A,Udot,F);CHKERRQ(ierr); 3579 PetscFunctionReturn(0); 3580 } 3581 3582 #undef __FUNCT__ 3583 #define __FUNCT__ "TSComputeIJacobianConstant" 3584 /*@C 3585 TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE 3586 3587 Collective on TS 3588 3589 Input Arguments: 3590 + ts - time stepping context 3591 . t - time at which to evaluate 3592 . U - state at which to evaluate 3593 . Udot - time derivative of state vector 3594 . shift - shift to apply 3595 - ctx - context 3596 3597 Output Arguments: 3598 + A - pointer to operator 3599 . B - pointer to preconditioning matrix 3600 - flg - matrix structure flag 3601 3602 Level: advanced 3603 3604 Notes: 3605 This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems. 3606 3607 It is only appropriate for problems of the form 3608 3609 $ M Udot = F(U,t) 3610 3611 where M is constant and F is non-stiff. The user must pass M to TSSetIJacobian(). The current implementation only 3612 works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing 3613 an implicit operator of the form 3614 3615 $ shift*M + J 3616 3617 where J is the Jacobian of -F(U). Support may be added in a future version of PETSc, but for now, the user must store 3618 a copy of M or reassemble it when requested. 3619 3620 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear() 3621 @*/ 3622 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,void *ctx) 3623 { 3624 PetscErrorCode ierr; 3625 3626 PetscFunctionBegin; 3627 ierr = MatScale(*A, shift / ts->ijacobian.shift);CHKERRQ(ierr); 3628 ts->ijacobian.shift = shift; 3629 *flg = SAME_PRECONDITIONER; 3630 PetscFunctionReturn(0); 3631 } 3632 3633 #undef __FUNCT__ 3634 #define __FUNCT__ "TSGetEquationType" 3635 /*@ 3636 TSGetEquationType - Gets the type of the equation that TS is solving. 3637 3638 Not Collective 3639 3640 Input Parameter: 3641 . ts - the TS context 3642 3643 Output Parameter: 3644 . equation_type - see TSEquationType 3645 3646 Level: beginner 3647 3648 .keywords: TS, equation type 3649 3650 .seealso: TSSetEquationType(), TSEquationType 3651 @*/ 3652 PetscErrorCode TSGetEquationType(TS ts,TSEquationType *equation_type) 3653 { 3654 PetscFunctionBegin; 3655 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3656 PetscValidPointer(equation_type,2); 3657 *equation_type = ts->equation_type; 3658 PetscFunctionReturn(0); 3659 } 3660 3661 #undef __FUNCT__ 3662 #define __FUNCT__ "TSSetEquationType" 3663 /*@ 3664 TSSetEquationType - Sets the type of the equation that TS is solving. 3665 3666 Not Collective 3667 3668 Input Parameter: 3669 + ts - the TS context 3670 . equation_type - see TSEquationType 3671 3672 Level: advanced 3673 3674 .keywords: TS, equation type 3675 3676 .seealso: TSGetEquationType(), TSEquationType 3677 @*/ 3678 PetscErrorCode TSSetEquationType(TS ts,TSEquationType equation_type) 3679 { 3680 PetscFunctionBegin; 3681 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3682 ts->equation_type = equation_type; 3683 PetscFunctionReturn(0); 3684 } 3685 3686 #undef __FUNCT__ 3687 #define __FUNCT__ "TSGetConvergedReason" 3688 /*@ 3689 TSGetConvergedReason - Gets the reason the TS iteration was stopped. 3690 3691 Not Collective 3692 3693 Input Parameter: 3694 . ts - the TS context 3695 3696 Output Parameter: 3697 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 3698 manual pages for the individual convergence tests for complete lists 3699 3700 Level: beginner 3701 3702 Notes: 3703 Can only be called after the call to TSSolve() is complete. 3704 3705 .keywords: TS, nonlinear, set, convergence, test 3706 3707 .seealso: TSSetConvergenceTest(), TSConvergedReason 3708 @*/ 3709 PetscErrorCode TSGetConvergedReason(TS ts,TSConvergedReason *reason) 3710 { 3711 PetscFunctionBegin; 3712 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3713 PetscValidPointer(reason,2); 3714 *reason = ts->reason; 3715 PetscFunctionReturn(0); 3716 } 3717 3718 #undef __FUNCT__ 3719 #define __FUNCT__ "TSSetConvergedReason" 3720 /*@ 3721 TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve. 3722 3723 Not Collective 3724 3725 Input Parameter: 3726 + ts - the TS context 3727 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 3728 manual pages for the individual convergence tests for complete lists 3729 3730 Level: advanced 3731 3732 Notes: 3733 Can only be called during TSSolve() is active. 3734 3735 .keywords: TS, nonlinear, set, convergence, test 3736 3737 .seealso: TSConvergedReason 3738 @*/ 3739 PetscErrorCode TSSetConvergedReason(TS ts,TSConvergedReason reason) 3740 { 3741 PetscFunctionBegin; 3742 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3743 ts->reason = reason; 3744 PetscFunctionReturn(0); 3745 } 3746 3747 #undef __FUNCT__ 3748 #define __FUNCT__ "TSGetSolveTime" 3749 /*@ 3750 TSGetSolveTime - Gets the time after a call to TSSolve() 3751 3752 Not Collective 3753 3754 Input Parameter: 3755 . ts - the TS context 3756 3757 Output Parameter: 3758 . ftime - the final time. This time should correspond to the final time set with TSSetDuration() 3759 3760 Level: beginner 3761 3762 Notes: 3763 Can only be called after the call to TSSolve() is complete. 3764 3765 .keywords: TS, nonlinear, set, convergence, test 3766 3767 .seealso: TSSetConvergenceTest(), TSConvergedReason 3768 @*/ 3769 PetscErrorCode TSGetSolveTime(TS ts,PetscReal *ftime) 3770 { 3771 PetscFunctionBegin; 3772 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3773 PetscValidPointer(ftime,2); 3774 *ftime = ts->solvetime; 3775 PetscFunctionReturn(0); 3776 } 3777 3778 #undef __FUNCT__ 3779 #define __FUNCT__ "TSGetSNESIterations" 3780 /*@ 3781 TSGetSNESIterations - Gets the total number of nonlinear iterations 3782 used by the time integrator. 3783 3784 Not Collective 3785 3786 Input Parameter: 3787 . ts - TS context 3788 3789 Output Parameter: 3790 . nits - number of nonlinear iterations 3791 3792 Notes: 3793 This counter is reset to zero for each successive call to TSSolve(). 3794 3795 Level: intermediate 3796 3797 .keywords: TS, get, number, nonlinear, iterations 3798 3799 .seealso: TSGetKSPIterations() 3800 @*/ 3801 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits) 3802 { 3803 PetscFunctionBegin; 3804 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3805 PetscValidIntPointer(nits,2); 3806 *nits = ts->snes_its; 3807 PetscFunctionReturn(0); 3808 } 3809 3810 #undef __FUNCT__ 3811 #define __FUNCT__ "TSGetKSPIterations" 3812 /*@ 3813 TSGetKSPIterations - Gets the total number of linear iterations 3814 used by the time integrator. 3815 3816 Not Collective 3817 3818 Input Parameter: 3819 . ts - TS context 3820 3821 Output Parameter: 3822 . lits - number of linear iterations 3823 3824 Notes: 3825 This counter is reset to zero for each successive call to TSSolve(). 3826 3827 Level: intermediate 3828 3829 .keywords: TS, get, number, linear, iterations 3830 3831 .seealso: TSGetSNESIterations(), SNESGetKSPIterations() 3832 @*/ 3833 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits) 3834 { 3835 PetscFunctionBegin; 3836 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3837 PetscValidIntPointer(lits,2); 3838 *lits = ts->ksp_its; 3839 PetscFunctionReturn(0); 3840 } 3841 3842 #undef __FUNCT__ 3843 #define __FUNCT__ "TSGetStepRejections" 3844 /*@ 3845 TSGetStepRejections - Gets the total number of rejected steps. 3846 3847 Not Collective 3848 3849 Input Parameter: 3850 . ts - TS context 3851 3852 Output Parameter: 3853 . rejects - number of steps rejected 3854 3855 Notes: 3856 This counter is reset to zero for each successive call to TSSolve(). 3857 3858 Level: intermediate 3859 3860 .keywords: TS, get, number 3861 3862 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails() 3863 @*/ 3864 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects) 3865 { 3866 PetscFunctionBegin; 3867 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3868 PetscValidIntPointer(rejects,2); 3869 *rejects = ts->reject; 3870 PetscFunctionReturn(0); 3871 } 3872 3873 #undef __FUNCT__ 3874 #define __FUNCT__ "TSGetSNESFailures" 3875 /*@ 3876 TSGetSNESFailures - Gets the total number of failed SNES solves 3877 3878 Not Collective 3879 3880 Input Parameter: 3881 . ts - TS context 3882 3883 Output Parameter: 3884 . fails - number of failed nonlinear solves 3885 3886 Notes: 3887 This counter is reset to zero for each successive call to TSSolve(). 3888 3889 Level: intermediate 3890 3891 .keywords: TS, get, number 3892 3893 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures() 3894 @*/ 3895 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails) 3896 { 3897 PetscFunctionBegin; 3898 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3899 PetscValidIntPointer(fails,2); 3900 *fails = ts->num_snes_failures; 3901 PetscFunctionReturn(0); 3902 } 3903 3904 #undef __FUNCT__ 3905 #define __FUNCT__ "TSSetMaxStepRejections" 3906 /*@ 3907 TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails 3908 3909 Not Collective 3910 3911 Input Parameter: 3912 + ts - TS context 3913 - rejects - maximum number of rejected steps, pass -1 for unlimited 3914 3915 Notes: 3916 The counter is reset to zero for each step 3917 3918 Options Database Key: 3919 . -ts_max_reject - Maximum number of step rejections before a step fails 3920 3921 Level: intermediate 3922 3923 .keywords: TS, set, maximum, number 3924 3925 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 3926 @*/ 3927 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects) 3928 { 3929 PetscFunctionBegin; 3930 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3931 ts->max_reject = rejects; 3932 PetscFunctionReturn(0); 3933 } 3934 3935 #undef __FUNCT__ 3936 #define __FUNCT__ "TSSetMaxSNESFailures" 3937 /*@ 3938 TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves 3939 3940 Not Collective 3941 3942 Input Parameter: 3943 + ts - TS context 3944 - fails - maximum number of failed nonlinear solves, pass -1 for unlimited 3945 3946 Notes: 3947 The counter is reset to zero for each successive call to TSSolve(). 3948 3949 Options Database Key: 3950 . -ts_max_snes_failures - Maximum number of nonlinear solve failures 3951 3952 Level: intermediate 3953 3954 .keywords: TS, set, maximum, number 3955 3956 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason() 3957 @*/ 3958 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails) 3959 { 3960 PetscFunctionBegin; 3961 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3962 ts->max_snes_failures = fails; 3963 PetscFunctionReturn(0); 3964 } 3965 3966 #undef __FUNCT__ 3967 #define __FUNCT__ "TSSetErrorIfStepFails()" 3968 /*@ 3969 TSSetErrorIfStepFails - Error if no step succeeds 3970 3971 Not Collective 3972 3973 Input Parameter: 3974 + ts - TS context 3975 - err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure 3976 3977 Options Database Key: 3978 . -ts_error_if_step_fails - Error if no step succeeds 3979 3980 Level: intermediate 3981 3982 .keywords: TS, set, error 3983 3984 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 3985 @*/ 3986 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err) 3987 { 3988 PetscFunctionBegin; 3989 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3990 ts->errorifstepfailed = err; 3991 PetscFunctionReturn(0); 3992 } 3993 3994 #undef __FUNCT__ 3995 #define __FUNCT__ "TSMonitorSolutionBinary" 3996 /*@C 3997 TSMonitorSolutionBinary - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file 3998 3999 Collective on TS 4000 4001 Input Parameters: 4002 + ts - the TS context 4003 . step - current time-step 4004 . ptime - current time 4005 . u - current state 4006 - viewer - binary viewer 4007 4008 Level: intermediate 4009 4010 .keywords: TS, vector, monitor, view 4011 4012 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4013 @*/ 4014 PetscErrorCode TSMonitorSolutionBinary(TS ts,PetscInt step,PetscReal ptime,Vec u,void *viewer) 4015 { 4016 PetscErrorCode ierr; 4017 PetscViewer v = (PetscViewer)viewer; 4018 4019 PetscFunctionBegin; 4020 ierr = VecView(u,v);CHKERRQ(ierr); 4021 PetscFunctionReturn(0); 4022 } 4023 4024 #undef __FUNCT__ 4025 #define __FUNCT__ "TSMonitorSolutionVTK" 4026 /*@C 4027 TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep. 4028 4029 Collective on TS 4030 4031 Input Parameters: 4032 + ts - the TS context 4033 . step - current time-step 4034 . ptime - current time 4035 . u - current state 4036 - filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 4037 4038 Level: intermediate 4039 4040 Notes: 4041 The VTK format does not allow writing multiple time steps in the same file, therefore a different file will be written for each time step. 4042 These are named according to the file name template. 4043 4044 This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy(). 4045 4046 .keywords: TS, vector, monitor, view 4047 4048 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4049 @*/ 4050 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate) 4051 { 4052 PetscErrorCode ierr; 4053 char filename[PETSC_MAX_PATH_LEN]; 4054 PetscViewer viewer; 4055 4056 PetscFunctionBegin; 4057 ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr); 4058 ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); 4059 ierr = VecView(u,viewer);CHKERRQ(ierr); 4060 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4061 PetscFunctionReturn(0); 4062 } 4063 4064 #undef __FUNCT__ 4065 #define __FUNCT__ "TSMonitorSolutionVTKDestroy" 4066 /*@C 4067 TSMonitorSolutionVTKDestroy - Destroy context for monitoring 4068 4069 Collective on TS 4070 4071 Input Parameters: 4072 . filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 4073 4074 Level: intermediate 4075 4076 Note: 4077 This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK(). 4078 4079 .keywords: TS, vector, monitor, view 4080 4081 .seealso: TSMonitorSet(), TSMonitorSolutionVTK() 4082 @*/ 4083 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate) 4084 { 4085 PetscErrorCode ierr; 4086 4087 PetscFunctionBegin; 4088 ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr); 4089 PetscFunctionReturn(0); 4090 } 4091 4092 #undef __FUNCT__ 4093 #define __FUNCT__ "TSGetAdapt" 4094 /*@ 4095 TSGetAdapt - Get the adaptive controller context for the current method 4096 4097 Collective on TS if controller has not been created yet 4098 4099 Input Arguments: 4100 . ts - time stepping context 4101 4102 Output Arguments: 4103 . adapt - adaptive controller 4104 4105 Level: intermediate 4106 4107 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose() 4108 @*/ 4109 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt) 4110 { 4111 PetscErrorCode ierr; 4112 4113 PetscFunctionBegin; 4114 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4115 PetscValidPointer(adapt,2); 4116 if (!ts->adapt) { 4117 ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr); 4118 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr); 4119 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr); 4120 } 4121 *adapt = ts->adapt; 4122 PetscFunctionReturn(0); 4123 } 4124 4125 #undef __FUNCT__ 4126 #define __FUNCT__ "TSSetTolerances" 4127 /*@ 4128 TSSetTolerances - Set tolerances for local truncation error when using adaptive controller 4129 4130 Logically Collective 4131 4132 Input Arguments: 4133 + ts - time integration context 4134 . atol - scalar absolute tolerances, PETSC_DECIDE to leave current value 4135 . vatol - vector of absolute tolerances or NULL, used in preference to atol if present 4136 . rtol - scalar relative tolerances, PETSC_DECIDE to leave current value 4137 - vrtol - vector of relative tolerances or NULL, used in preference to atol if present 4138 4139 Level: beginner 4140 4141 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances() 4142 @*/ 4143 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol) 4144 { 4145 PetscErrorCode ierr; 4146 4147 PetscFunctionBegin; 4148 if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol; 4149 if (vatol) { 4150 ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr); 4151 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 4152 4153 ts->vatol = vatol; 4154 } 4155 if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol; 4156 if (vrtol) { 4157 ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr); 4158 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 4159 4160 ts->vrtol = vrtol; 4161 } 4162 PetscFunctionReturn(0); 4163 } 4164 4165 #undef __FUNCT__ 4166 #define __FUNCT__ "TSGetTolerances" 4167 /*@ 4168 TSGetTolerances - Get tolerances for local truncation error when using adaptive controller 4169 4170 Logically Collective 4171 4172 Input Arguments: 4173 . ts - time integration context 4174 4175 Output Arguments: 4176 + atol - scalar absolute tolerances, NULL to ignore 4177 . vatol - vector of absolute tolerances, NULL to ignore 4178 . rtol - scalar relative tolerances, NULL to ignore 4179 - vrtol - vector of relative tolerances, NULL to ignore 4180 4181 Level: beginner 4182 4183 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances() 4184 @*/ 4185 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol) 4186 { 4187 PetscFunctionBegin; 4188 if (atol) *atol = ts->atol; 4189 if (vatol) *vatol = ts->vatol; 4190 if (rtol) *rtol = ts->rtol; 4191 if (vrtol) *vrtol = ts->vrtol; 4192 PetscFunctionReturn(0); 4193 } 4194 4195 #undef __FUNCT__ 4196 #define __FUNCT__ "TSErrorNormWRMS" 4197 /*@ 4198 TSErrorNormWRMS - compute a weighted norm of the difference between a vector and the current state 4199 4200 Collective on TS 4201 4202 Input Arguments: 4203 + ts - time stepping context 4204 - Y - state vector to be compared to ts->vec_sol 4205 4206 Output Arguments: 4207 . norm - weighted norm, a value of 1.0 is considered small 4208 4209 Level: developer 4210 4211 .seealso: TSSetTolerances() 4212 @*/ 4213 PetscErrorCode TSErrorNormWRMS(TS ts,Vec Y,PetscReal *norm) 4214 { 4215 PetscErrorCode ierr; 4216 PetscInt i,n,N; 4217 const PetscScalar *u,*y; 4218 Vec U; 4219 PetscReal sum,gsum; 4220 4221 PetscFunctionBegin; 4222 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4223 PetscValidHeaderSpecific(Y,VEC_CLASSID,2); 4224 PetscValidPointer(norm,3); 4225 U = ts->vec_sol; 4226 PetscCheckSameTypeAndComm(U,1,Y,2); 4227 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"Y cannot be the TS solution vector"); 4228 4229 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 4230 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 4231 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 4232 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 4233 sum = 0.; 4234 if (ts->vatol && ts->vrtol) { 4235 const PetscScalar *atol,*rtol; 4236 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 4237 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 4238 for (i=0; i<n; i++) { 4239 PetscReal tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 4240 sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol); 4241 } 4242 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 4243 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 4244 } else if (ts->vatol) { /* vector atol, scalar rtol */ 4245 const PetscScalar *atol; 4246 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 4247 for (i=0; i<n; i++) { 4248 PetscReal tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 4249 sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol); 4250 } 4251 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 4252 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 4253 const PetscScalar *rtol; 4254 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 4255 for (i=0; i<n; i++) { 4256 PetscReal tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 4257 sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol); 4258 } 4259 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 4260 } else { /* scalar atol, scalar rtol */ 4261 for (i=0; i<n; i++) { 4262 PetscReal tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 4263 sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol); 4264 } 4265 } 4266 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 4267 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 4268 4269 ierr = MPI_Allreduce(&sum,&gsum,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 4270 *norm = PetscSqrtReal(gsum / N); 4271 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 4272 PetscFunctionReturn(0); 4273 } 4274 4275 #undef __FUNCT__ 4276 #define __FUNCT__ "TSSetCFLTimeLocal" 4277 /*@ 4278 TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler 4279 4280 Logically Collective on TS 4281 4282 Input Arguments: 4283 + ts - time stepping context 4284 - cfltime - maximum stable time step if using forward Euler (value can be different on each process) 4285 4286 Note: 4287 After calling this function, the global CFL time can be obtained by calling TSGetCFLTime() 4288 4289 Level: intermediate 4290 4291 .seealso: TSGetCFLTime(), TSADAPTCFL 4292 @*/ 4293 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime) 4294 { 4295 PetscFunctionBegin; 4296 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4297 ts->cfltime_local = cfltime; 4298 ts->cfltime = -1.; 4299 PetscFunctionReturn(0); 4300 } 4301 4302 #undef __FUNCT__ 4303 #define __FUNCT__ "TSGetCFLTime" 4304 /*@ 4305 TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler 4306 4307 Collective on TS 4308 4309 Input Arguments: 4310 . ts - time stepping context 4311 4312 Output Arguments: 4313 . cfltime - maximum stable time step for forward Euler 4314 4315 Level: advanced 4316 4317 .seealso: TSSetCFLTimeLocal() 4318 @*/ 4319 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime) 4320 { 4321 PetscErrorCode ierr; 4322 4323 PetscFunctionBegin; 4324 if (ts->cfltime < 0) { 4325 ierr = MPI_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 4326 } 4327 *cfltime = ts->cfltime; 4328 PetscFunctionReturn(0); 4329 } 4330 4331 #undef __FUNCT__ 4332 #define __FUNCT__ "TSVISetVariableBounds" 4333 /*@ 4334 TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu 4335 4336 Input Parameters: 4337 . ts - the TS context. 4338 . xl - lower bound. 4339 . xu - upper bound. 4340 4341 Notes: 4342 If this routine is not called then the lower and upper bounds are set to 4343 SNES_VI_NINF and SNES_VI_INF respectively during SNESSetUp(). 4344 4345 Level: advanced 4346 4347 @*/ 4348 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu) 4349 { 4350 PetscErrorCode ierr; 4351 SNES snes; 4352 4353 PetscFunctionBegin; 4354 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4355 ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr); 4356 PetscFunctionReturn(0); 4357 } 4358 4359 #if defined(PETSC_HAVE_MATLAB_ENGINE) 4360 #include <mex.h> 4361 4362 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext; 4363 4364 #undef __FUNCT__ 4365 #define __FUNCT__ "TSComputeFunction_Matlab" 4366 /* 4367 TSComputeFunction_Matlab - Calls the function that has been set with 4368 TSSetFunctionMatlab(). 4369 4370 Collective on TS 4371 4372 Input Parameters: 4373 + snes - the TS context 4374 - u - input vector 4375 4376 Output Parameter: 4377 . y - function vector, as set by TSSetFunction() 4378 4379 Notes: 4380 TSComputeFunction() is typically used within nonlinear solvers 4381 implementations, so most users would not generally call this routine 4382 themselves. 4383 4384 Level: developer 4385 4386 .keywords: TS, nonlinear, compute, function 4387 4388 .seealso: TSSetFunction(), TSGetFunction() 4389 */ 4390 PetscErrorCode TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx) 4391 { 4392 PetscErrorCode ierr; 4393 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 4394 int nlhs = 1,nrhs = 7; 4395 mxArray *plhs[1],*prhs[7]; 4396 long long int lx = 0,lxdot = 0,ly = 0,ls = 0; 4397 4398 PetscFunctionBegin; 4399 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 4400 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 4401 PetscValidHeaderSpecific(udot,VEC_CLASSID,4); 4402 PetscValidHeaderSpecific(y,VEC_CLASSID,5); 4403 PetscCheckSameComm(snes,1,u,3); 4404 PetscCheckSameComm(snes,1,y,5); 4405 4406 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4407 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 4408 ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr); 4409 ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr); 4410 4411 prhs[0] = mxCreateDoubleScalar((double)ls); 4412 prhs[1] = mxCreateDoubleScalar(time); 4413 prhs[2] = mxCreateDoubleScalar((double)lx); 4414 prhs[3] = mxCreateDoubleScalar((double)lxdot); 4415 prhs[4] = mxCreateDoubleScalar((double)ly); 4416 prhs[5] = mxCreateString(sctx->funcname); 4417 prhs[6] = sctx->ctx; 4418 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr); 4419 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4420 mxDestroyArray(prhs[0]); 4421 mxDestroyArray(prhs[1]); 4422 mxDestroyArray(prhs[2]); 4423 mxDestroyArray(prhs[3]); 4424 mxDestroyArray(prhs[4]); 4425 mxDestroyArray(prhs[5]); 4426 mxDestroyArray(plhs[0]); 4427 PetscFunctionReturn(0); 4428 } 4429 4430 4431 #undef __FUNCT__ 4432 #define __FUNCT__ "TSSetFunctionMatlab" 4433 /* 4434 TSSetFunctionMatlab - Sets the function evaluation routine and function 4435 vector for use by the TS routines in solving ODEs 4436 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 4437 4438 Logically Collective on TS 4439 4440 Input Parameters: 4441 + ts - the TS context 4442 - func - function evaluation routine 4443 4444 Calling sequence of func: 4445 $ func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx); 4446 4447 Level: beginner 4448 4449 .keywords: TS, nonlinear, set, function 4450 4451 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 4452 */ 4453 PetscErrorCode TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx) 4454 { 4455 PetscErrorCode ierr; 4456 TSMatlabContext *sctx; 4457 4458 PetscFunctionBegin; 4459 /* currently sctx is memory bleed */ 4460 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 4461 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4462 /* 4463 This should work, but it doesn't 4464 sctx->ctx = ctx; 4465 mexMakeArrayPersistent(sctx->ctx); 4466 */ 4467 sctx->ctx = mxDuplicateArray(ctx); 4468 4469 ierr = TSSetIFunction(ts,NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr); 4470 PetscFunctionReturn(0); 4471 } 4472 4473 #undef __FUNCT__ 4474 #define __FUNCT__ "TSComputeJacobian_Matlab" 4475 /* 4476 TSComputeJacobian_Matlab - Calls the function that has been set with 4477 TSSetJacobianMatlab(). 4478 4479 Collective on TS 4480 4481 Input Parameters: 4482 + ts - the TS context 4483 . u - input vector 4484 . A, B - the matrices 4485 - ctx - user context 4486 4487 Output Parameter: 4488 . flag - structure of the matrix 4489 4490 Level: developer 4491 4492 .keywords: TS, nonlinear, compute, function 4493 4494 .seealso: TSSetFunction(), TSGetFunction() 4495 @*/ 4496 PetscErrorCode TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flag, void *ctx) 4497 { 4498 PetscErrorCode ierr; 4499 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 4500 int nlhs = 2,nrhs = 9; 4501 mxArray *plhs[2],*prhs[9]; 4502 long long int lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0; 4503 4504 PetscFunctionBegin; 4505 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4506 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 4507 4508 /* call Matlab function in ctx with arguments u and y */ 4509 4510 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 4511 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 4512 ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr); 4513 ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr); 4514 ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr); 4515 4516 prhs[0] = mxCreateDoubleScalar((double)ls); 4517 prhs[1] = mxCreateDoubleScalar((double)time); 4518 prhs[2] = mxCreateDoubleScalar((double)lx); 4519 prhs[3] = mxCreateDoubleScalar((double)lxdot); 4520 prhs[4] = mxCreateDoubleScalar((double)shift); 4521 prhs[5] = mxCreateDoubleScalar((double)lA); 4522 prhs[6] = mxCreateDoubleScalar((double)lB); 4523 prhs[7] = mxCreateString(sctx->funcname); 4524 prhs[8] = sctx->ctx; 4525 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr); 4526 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4527 *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 4528 mxDestroyArray(prhs[0]); 4529 mxDestroyArray(prhs[1]); 4530 mxDestroyArray(prhs[2]); 4531 mxDestroyArray(prhs[3]); 4532 mxDestroyArray(prhs[4]); 4533 mxDestroyArray(prhs[5]); 4534 mxDestroyArray(prhs[6]); 4535 mxDestroyArray(prhs[7]); 4536 mxDestroyArray(plhs[0]); 4537 mxDestroyArray(plhs[1]); 4538 PetscFunctionReturn(0); 4539 } 4540 4541 4542 #undef __FUNCT__ 4543 #define __FUNCT__ "TSSetJacobianMatlab" 4544 /* 4545 TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 4546 vector for use by the TS routines in solving ODEs from MATLAB. Here the function is a string containing the name of a MATLAB function 4547 4548 Logically Collective on TS 4549 4550 Input Parameters: 4551 + ts - the TS context 4552 . A,B - Jacobian matrices 4553 . func - function evaluation routine 4554 - ctx - user context 4555 4556 Calling sequence of func: 4557 $ flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx); 4558 4559 4560 Level: developer 4561 4562 .keywords: TS, nonlinear, set, function 4563 4564 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 4565 */ 4566 PetscErrorCode TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx) 4567 { 4568 PetscErrorCode ierr; 4569 TSMatlabContext *sctx; 4570 4571 PetscFunctionBegin; 4572 /* currently sctx is memory bleed */ 4573 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 4574 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4575 /* 4576 This should work, but it doesn't 4577 sctx->ctx = ctx; 4578 mexMakeArrayPersistent(sctx->ctx); 4579 */ 4580 sctx->ctx = mxDuplicateArray(ctx); 4581 4582 ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 4583 PetscFunctionReturn(0); 4584 } 4585 4586 #undef __FUNCT__ 4587 #define __FUNCT__ "TSMonitor_Matlab" 4588 /* 4589 TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab(). 4590 4591 Collective on TS 4592 4593 .seealso: TSSetFunction(), TSGetFunction() 4594 @*/ 4595 PetscErrorCode TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx) 4596 { 4597 PetscErrorCode ierr; 4598 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 4599 int nlhs = 1,nrhs = 6; 4600 mxArray *plhs[1],*prhs[6]; 4601 long long int lx = 0,ls = 0; 4602 4603 PetscFunctionBegin; 4604 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4605 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 4606 4607 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 4608 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 4609 4610 prhs[0] = mxCreateDoubleScalar((double)ls); 4611 prhs[1] = mxCreateDoubleScalar((double)it); 4612 prhs[2] = mxCreateDoubleScalar((double)time); 4613 prhs[3] = mxCreateDoubleScalar((double)lx); 4614 prhs[4] = mxCreateString(sctx->funcname); 4615 prhs[5] = sctx->ctx; 4616 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr); 4617 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4618 mxDestroyArray(prhs[0]); 4619 mxDestroyArray(prhs[1]); 4620 mxDestroyArray(prhs[2]); 4621 mxDestroyArray(prhs[3]); 4622 mxDestroyArray(prhs[4]); 4623 mxDestroyArray(plhs[0]); 4624 PetscFunctionReturn(0); 4625 } 4626 4627 4628 #undef __FUNCT__ 4629 #define __FUNCT__ "TSMonitorSetMatlab" 4630 /* 4631 TSMonitorSetMatlab - Sets the monitor function from Matlab 4632 4633 Level: developer 4634 4635 .keywords: TS, nonlinear, set, function 4636 4637 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 4638 */ 4639 PetscErrorCode TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx) 4640 { 4641 PetscErrorCode ierr; 4642 TSMatlabContext *sctx; 4643 4644 PetscFunctionBegin; 4645 /* currently sctx is memory bleed */ 4646 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 4647 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4648 /* 4649 This should work, but it doesn't 4650 sctx->ctx = ctx; 4651 mexMakeArrayPersistent(sctx->ctx); 4652 */ 4653 sctx->ctx = mxDuplicateArray(ctx); 4654 4655 ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,NULL);CHKERRQ(ierr); 4656 PetscFunctionReturn(0); 4657 } 4658 #endif 4659 4660 4661 4662 #undef __FUNCT__ 4663 #define __FUNCT__ "TSMonitorLGSolution" 4664 /*@C 4665 TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector 4666 in a time based line graph 4667 4668 Collective on TS 4669 4670 Input Parameters: 4671 + ts - the TS context 4672 . step - current time-step 4673 . ptime - current time 4674 - lg - a line graph object 4675 4676 Level: intermediate 4677 4678 Notes: each process in a parallel run displays its component solutions in a separate window 4679 4680 .keywords: TS, vector, monitor, view 4681 4682 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4683 @*/ 4684 PetscErrorCode TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4685 { 4686 PetscErrorCode ierr; 4687 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 4688 const PetscScalar *yy; 4689 PetscInt dim; 4690 4691 PetscFunctionBegin; 4692 if (!step) { 4693 PetscDrawAxis axis; 4694 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 4695 ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr); 4696 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 4697 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 4698 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 4699 } 4700 ierr = VecGetArrayRead(u,&yy);CHKERRQ(ierr); 4701 #if defined(PETSC_USE_COMPLEX) 4702 { 4703 PetscReal *yreal; 4704 PetscInt i,n; 4705 ierr = VecGetLocalSize(u,&n);CHKERRQ(ierr); 4706 ierr = PetscMalloc(n*sizeof(PetscReal),&yreal);CHKERRQ(ierr); 4707 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 4708 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 4709 ierr = PetscFree(yreal);CHKERRQ(ierr); 4710 } 4711 #else 4712 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 4713 #endif 4714 ierr = VecRestoreArrayRead(u,&yy);CHKERRQ(ierr); 4715 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 4716 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 4717 } 4718 PetscFunctionReturn(0); 4719 } 4720 4721 #undef __FUNCT__ 4722 #define __FUNCT__ "TSMonitorLGError" 4723 /*@C 4724 TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the solution vector 4725 in a time based line graph 4726 4727 Collective on TS 4728 4729 Input Parameters: 4730 + ts - the TS context 4731 . step - current time-step 4732 . ptime - current time 4733 - lg - a line graph object 4734 4735 Level: intermediate 4736 4737 Notes: 4738 Only for sequential solves. 4739 4740 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 4741 4742 Options Database Keys: 4743 . -ts_monitor_lg_error - create a graphical monitor of error history 4744 4745 .keywords: TS, vector, monitor, view 4746 4747 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 4748 @*/ 4749 PetscErrorCode TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4750 { 4751 PetscErrorCode ierr; 4752 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 4753 const PetscScalar *yy; 4754 Vec y; 4755 PetscInt dim; 4756 4757 PetscFunctionBegin; 4758 if (!step) { 4759 PetscDrawAxis axis; 4760 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 4761 ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Solution");CHKERRQ(ierr); 4762 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 4763 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 4764 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 4765 } 4766 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 4767 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 4768 ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr); 4769 ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr); 4770 #if defined(PETSC_USE_COMPLEX) 4771 { 4772 PetscReal *yreal; 4773 PetscInt i,n; 4774 ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr); 4775 ierr = PetscMalloc(n*sizeof(PetscReal),&yreal);CHKERRQ(ierr); 4776 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 4777 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 4778 ierr = PetscFree(yreal);CHKERRQ(ierr); 4779 } 4780 #else 4781 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 4782 #endif 4783 ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr); 4784 ierr = VecDestroy(&y);CHKERRQ(ierr); 4785 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 4786 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 4787 } 4788 PetscFunctionReturn(0); 4789 } 4790 4791 #undef __FUNCT__ 4792 #define __FUNCT__ "TSMonitorLGSNESIterations" 4793 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 4794 { 4795 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 4796 PetscReal x = ptime,y; 4797 PetscErrorCode ierr; 4798 PetscInt its; 4799 4800 PetscFunctionBegin; 4801 if (!n) { 4802 PetscDrawAxis axis; 4803 4804 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 4805 ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr); 4806 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 4807 4808 ctx->snes_its = 0; 4809 } 4810 ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr); 4811 y = its - ctx->snes_its; 4812 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 4813 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 4814 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 4815 } 4816 ctx->snes_its = its; 4817 PetscFunctionReturn(0); 4818 } 4819 4820 #undef __FUNCT__ 4821 #define __FUNCT__ "TSMonitorLGKSPIterations" 4822 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 4823 { 4824 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 4825 PetscReal x = ptime,y; 4826 PetscErrorCode ierr; 4827 PetscInt its; 4828 4829 PetscFunctionBegin; 4830 if (!n) { 4831 PetscDrawAxis axis; 4832 4833 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 4834 ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr); 4835 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 4836 4837 ctx->ksp_its = 0; 4838 } 4839 ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr); 4840 y = its - ctx->ksp_its; 4841 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 4842 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 4843 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 4844 } 4845 ctx->ksp_its = its; 4846 PetscFunctionReturn(0); 4847 } 4848 4849 #undef __FUNCT__ 4850 #define __FUNCT__ "TSComputeLinearStability" 4851 /*@ 4852 TSComputeLinearStability - computes the linear stability function at a point 4853 4854 Collective on TS and Vec 4855 4856 Input Parameters: 4857 + ts - the TS context 4858 - xr,xi - real and imaginary part of input arguments 4859 4860 Output Parameters: 4861 . yr,yi - real and imaginary part of function value 4862 4863 Level: developer 4864 4865 .keywords: TS, compute 4866 4867 .seealso: TSSetRHSFunction(), TSComputeIFunction() 4868 @*/ 4869 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi) 4870 { 4871 PetscErrorCode ierr; 4872 4873 PetscFunctionBegin; 4874 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4875 if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method"); 4876 ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr); 4877 PetscFunctionReturn(0); 4878 } 4879