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