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