1 2 #include <private/tsimpl.h> /*I "petscts.h" I*/ 3 4 /* Logging support */ 5 PetscClassId TS_CLASSID; 6 PetscLogEvent TS_Step, TS_PseudoComputeTimeStep, TS_FunctionEval, TS_JacobianEval; 7 8 #undef __FUNCT__ 9 #define __FUNCT__ "TSSetTypeFromOptions" 10 /* 11 TSSetTypeFromOptions - Sets the type of ts from user options. 12 13 Collective on TS 14 15 Input Parameter: 16 . ts - The ts 17 18 Level: intermediate 19 20 .keywords: TS, set, options, database, type 21 .seealso: TSSetFromOptions(), TSSetType() 22 */ 23 static PetscErrorCode TSSetTypeFromOptions(TS ts) 24 { 25 PetscBool opt; 26 const char *defaultType; 27 char typeName[256]; 28 PetscErrorCode ierr; 29 30 PetscFunctionBegin; 31 if (((PetscObject)ts)->type_name) { 32 defaultType = ((PetscObject)ts)->type_name; 33 } else { 34 defaultType = TSEULER; 35 } 36 37 if (!TSRegisterAllCalled) {ierr = TSRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 38 ierr = PetscOptionsList("-ts_type", "TS method"," TSSetType", TSList, defaultType, typeName, 256, &opt);CHKERRQ(ierr); 39 if (opt) { 40 ierr = TSSetType(ts, typeName);CHKERRQ(ierr); 41 } else { 42 ierr = TSSetType(ts, defaultType);CHKERRQ(ierr); 43 } 44 PetscFunctionReturn(0); 45 } 46 47 #undef __FUNCT__ 48 #define __FUNCT__ "TSSetFromOptions" 49 /*@ 50 TSSetFromOptions - Sets various TS parameters from user options. 51 52 Collective on TS 53 54 Input Parameter: 55 . ts - the TS context obtained from TSCreate() 56 57 Options Database Keys: 58 + -ts_type <type> - TSEULER, TSBEULER, TSSUNDIALS, TSPSEUDO, TSCN, TSRK, TSTHETA, TSGL, TSSSP 59 . -ts_max_steps maxsteps - maximum number of time-steps to take 60 . -ts_max_time time - maximum time to compute to 61 . -ts_dt dt - initial time step 62 . -ts_monitor - print information at each timestep 63 - -ts_monitor_draw - plot information at each timestep 64 65 Level: beginner 66 67 .keywords: TS, timestep, set, options, database 68 69 .seealso: TSGetType() 70 @*/ 71 PetscErrorCode TSSetFromOptions(TS ts) 72 { 73 PetscReal dt; 74 PetscBool opt,flg; 75 PetscErrorCode ierr; 76 PetscViewer monviewer; 77 char monfilename[PETSC_MAX_PATH_LEN]; 78 SNES snes; 79 80 PetscFunctionBegin; 81 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 82 ierr = PetscOptionsBegin(((PetscObject)ts)->comm, ((PetscObject)ts)->prefix, "Time step options", "TS");CHKERRQ(ierr); 83 84 /* Handle generic TS options */ 85 ierr = PetscOptionsInt("-ts_max_steps","Maximum number of time steps","TSSetDuration",ts->max_steps,&ts->max_steps,PETSC_NULL);CHKERRQ(ierr); 86 ierr = PetscOptionsReal("-ts_max_time","Time to run to","TSSetDuration",ts->max_time,&ts->max_time,PETSC_NULL);CHKERRQ(ierr); 87 ierr = PetscOptionsReal("-ts_init_time","Initial time","TSSetInitialTime", ts->ptime, &ts->ptime, PETSC_NULL);CHKERRQ(ierr); 88 ierr = PetscOptionsReal("-ts_dt","Initial time step","TSSetInitialTimeStep",ts->initial_time_step,&dt,&opt);CHKERRQ(ierr); 89 if (opt) {ierr = TSSetInitialTimeStep(ts,ts->ptime,dt);CHKERRQ(ierr);} 90 ierr = PetscOptionsInt("-ts_max_snes_failures","Maximum number of nonlinear solve failures","",ts->max_snes_failures,&ts->max_snes_failures,PETSC_NULL);CHKERRQ(ierr); 91 ierr = PetscOptionsInt("-ts_max_reject","Maximum number of step rejections","",ts->max_reject,&ts->max_reject,PETSC_NULL);CHKERRQ(ierr); 92 ierr = PetscOptionsBool("-ts_error_if_step_failed","Error if no step succeeds","",ts->errorifstepfailed,&ts->errorifstepfailed,PETSC_NULL);CHKERRQ(ierr); 93 94 /* Monitor options */ 95 ierr = PetscOptionsString("-ts_monitor","Monitor timestep size","TSMonitorDefault","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 96 if (flg) { 97 ierr = PetscViewerASCIIOpen(((PetscObject)ts)->comm,monfilename,&monviewer);CHKERRQ(ierr); 98 ierr = TSMonitorSet(ts,TSMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 99 } 100 ierr = PetscOptionsString("-ts_monitor_python","Use Python function","TSMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 101 if (flg) {ierr = PetscPythonMonitorSet((PetscObject)ts,monfilename);CHKERRQ(ierr);} 102 103 opt = PETSC_FALSE; 104 ierr = PetscOptionsBool("-ts_monitor_draw","Monitor timestep size graphically","TSMonitorLG",opt,&opt,PETSC_NULL);CHKERRQ(ierr); 105 if (opt) { 106 ierr = TSMonitorSet(ts,TSMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 107 } 108 opt = PETSC_FALSE; 109 ierr = PetscOptionsBool("-ts_monitor_solution","Monitor solution graphically","TSMonitorSolution",opt,&opt,PETSC_NULL);CHKERRQ(ierr); 110 if (opt) { 111 ierr = TSMonitorSet(ts,TSMonitorSolution,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 112 } 113 114 /* Handle TS type options */ 115 ierr = TSSetTypeFromOptions(ts);CHKERRQ(ierr); 116 117 /* Handle specific TS options */ 118 if (ts->ops->setfromoptions) { 119 ierr = (*ts->ops->setfromoptions)(ts);CHKERRQ(ierr); 120 } 121 122 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 123 ierr = PetscObjectProcessOptionsHandlers((PetscObject)ts);CHKERRQ(ierr); 124 ierr = PetscOptionsEnd();CHKERRQ(ierr); 125 126 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 127 /* Handle subobject options */ 128 if (ts->problem_type == TS_LINEAR) {ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);} 129 ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); 130 PetscFunctionReturn(0); 131 } 132 133 #undef __FUNCT__ 134 #define __FUNCT__ "TSViewFromOptions" 135 /*@ 136 TSViewFromOptions - This function visualizes the ts based upon user options. 137 138 Collective on TS 139 140 Input Parameter: 141 . ts - The ts 142 143 Level: intermediate 144 145 .keywords: TS, view, options, database 146 .seealso: TSSetFromOptions(), TSView() 147 @*/ 148 PetscErrorCode TSViewFromOptions(TS ts,const char title[]) 149 { 150 PetscViewer viewer; 151 PetscDraw draw; 152 PetscBool opt = PETSC_FALSE; 153 char fileName[PETSC_MAX_PATH_LEN]; 154 PetscErrorCode ierr; 155 156 PetscFunctionBegin; 157 ierr = PetscOptionsGetString(((PetscObject)ts)->prefix, "-ts_view", fileName, PETSC_MAX_PATH_LEN, &opt);CHKERRQ(ierr); 158 if (opt && !PetscPreLoadingOn) { 159 ierr = PetscViewerASCIIOpen(((PetscObject)ts)->comm,fileName,&viewer);CHKERRQ(ierr); 160 ierr = TSView(ts, viewer);CHKERRQ(ierr); 161 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 162 } 163 opt = PETSC_FALSE; 164 ierr = PetscOptionsGetBool(((PetscObject)ts)->prefix, "-ts_view_draw", &opt,PETSC_NULL);CHKERRQ(ierr); 165 if (opt) { 166 ierr = PetscViewerDrawOpen(((PetscObject)ts)->comm, 0, 0, 0, 0, 300, 300, &viewer);CHKERRQ(ierr); 167 ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr); 168 if (title) { 169 ierr = PetscDrawSetTitle(draw, (char *)title);CHKERRQ(ierr); 170 } else { 171 ierr = PetscObjectName((PetscObject)ts);CHKERRQ(ierr); 172 ierr = PetscDrawSetTitle(draw, ((PetscObject)ts)->name);CHKERRQ(ierr); 173 } 174 ierr = TSView(ts, viewer);CHKERRQ(ierr); 175 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 176 ierr = PetscDrawPause(draw);CHKERRQ(ierr); 177 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 178 } 179 PetscFunctionReturn(0); 180 } 181 182 #undef __FUNCT__ 183 #define __FUNCT__ "TSComputeRHSJacobian" 184 /*@ 185 TSComputeRHSJacobian - Computes the Jacobian matrix that has been 186 set with TSSetRHSJacobian(). 187 188 Collective on TS and Vec 189 190 Input Parameters: 191 + ts - the TS context 192 . t - current timestep 193 - x - input vector 194 195 Output Parameters: 196 + A - Jacobian matrix 197 . B - optional preconditioning matrix 198 - flag - flag indicating matrix structure 199 200 Notes: 201 Most users should not need to explicitly call this routine, as it 202 is used internally within the nonlinear solvers. 203 204 See KSPSetOperators() for important information about setting the 205 flag parameter. 206 207 Level: developer 208 209 .keywords: SNES, compute, Jacobian, matrix 210 211 .seealso: TSSetRHSJacobian(), KSPSetOperators() 212 @*/ 213 PetscErrorCode TSComputeRHSJacobian(TS ts,PetscReal t,Vec X,Mat *A,Mat *B,MatStructure *flg) 214 { 215 PetscErrorCode ierr; 216 PetscInt Xstate; 217 218 PetscFunctionBegin; 219 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 220 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 221 PetscCheckSameComm(ts,1,X,3); 222 ierr = PetscObjectStateQuery((PetscObject)X,&Xstate);CHKERRQ(ierr); 223 if (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.X == X && ts->rhsjacobian.Xstate == Xstate))) { 224 *flg = ts->rhsjacobian.mstructure; 225 PetscFunctionReturn(0); 226 } 227 228 if (!ts->userops->rhsjacobian && !ts->userops->ijacobian) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()"); 229 230 if (ts->userops->rhsjacobian) { 231 ierr = PetscLogEventBegin(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr); 232 *flg = DIFFERENT_NONZERO_PATTERN; 233 PetscStackPush("TS user Jacobian function"); 234 ierr = (*ts->userops->rhsjacobian)(ts,t,X,A,B,flg,ts->jacP);CHKERRQ(ierr); 235 PetscStackPop; 236 ierr = PetscLogEventEnd(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr); 237 /* make sure user returned a correct Jacobian and preconditioner */ 238 PetscValidHeaderSpecific(*A,MAT_CLASSID,4); 239 PetscValidHeaderSpecific(*B,MAT_CLASSID,5); 240 } else { 241 ierr = MatZeroEntries(*A);CHKERRQ(ierr); 242 if (*A != *B) {ierr = MatZeroEntries(*B);CHKERRQ(ierr);} 243 *flg = SAME_NONZERO_PATTERN; 244 } 245 ts->rhsjacobian.time = t; 246 ts->rhsjacobian.X = X; 247 ierr = PetscObjectStateQuery((PetscObject)X,&ts->rhsjacobian.Xstate);CHKERRQ(ierr); 248 ts->rhsjacobian.mstructure = *flg; 249 PetscFunctionReturn(0); 250 } 251 252 #undef __FUNCT__ 253 #define __FUNCT__ "TSComputeRHSFunction" 254 /*@ 255 TSComputeRHSFunction - Evaluates the right-hand-side function. 256 257 Collective on TS and Vec 258 259 Input Parameters: 260 + ts - the TS context 261 . t - current time 262 - x - state vector 263 264 Output Parameter: 265 . y - right hand side 266 267 Note: 268 Most users should not need to explicitly call this routine, as it 269 is used internally within the nonlinear solvers. 270 271 Level: developer 272 273 .keywords: TS, compute 274 275 .seealso: TSSetRHSFunction(), TSComputeIFunction() 276 @*/ 277 PetscErrorCode TSComputeRHSFunction(TS ts,PetscReal t,Vec x,Vec y) 278 { 279 PetscErrorCode ierr; 280 281 PetscFunctionBegin; 282 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 283 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 284 PetscValidHeaderSpecific(y,VEC_CLASSID,4); 285 286 if (!ts->userops->rhsfunction && !ts->userops->ifunction) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 287 288 ierr = PetscLogEventBegin(TS_FunctionEval,ts,x,y,0);CHKERRQ(ierr); 289 if (ts->userops->rhsfunction) { 290 PetscStackPush("TS user right-hand-side function"); 291 ierr = (*ts->userops->rhsfunction)(ts,t,x,y,ts->funP);CHKERRQ(ierr); 292 PetscStackPop; 293 } else { 294 ierr = VecZeroEntries(y);CHKERRQ(ierr); 295 } 296 297 ierr = PetscLogEventEnd(TS_FunctionEval,ts,x,y,0);CHKERRQ(ierr); 298 PetscFunctionReturn(0); 299 } 300 301 #undef __FUNCT__ 302 #define __FUNCT__ "TSGetRHSVec_Private" 303 static PetscErrorCode TSGetRHSVec_Private(TS ts,Vec *Frhs) 304 { 305 PetscErrorCode ierr; 306 307 PetscFunctionBegin; 308 if (!ts->Frhs) { 309 ierr = VecDuplicate(ts->vec_sol,&ts->Frhs);CHKERRQ(ierr); 310 } 311 *Frhs = ts->Frhs; 312 PetscFunctionReturn(0); 313 } 314 315 #undef __FUNCT__ 316 #define __FUNCT__ "TSGetRHSMats_Private" 317 static PetscErrorCode TSGetRHSMats_Private(TS ts,Mat *Arhs,Mat *Brhs) 318 { 319 PetscErrorCode ierr; 320 Mat A,B; 321 322 PetscFunctionBegin; 323 ierr = TSGetIJacobian(ts,&A,&B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 324 if (Arhs) { 325 if (!ts->Arhs) { 326 ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&ts->Arhs);CHKERRQ(ierr); 327 } 328 *Arhs = ts->Arhs; 329 } 330 if (Brhs) { 331 if (!ts->Brhs) { 332 ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&ts->Brhs);CHKERRQ(ierr); 333 } 334 *Brhs = ts->Brhs; 335 } 336 PetscFunctionReturn(0); 337 } 338 339 #undef __FUNCT__ 340 #define __FUNCT__ "TSComputeIFunction" 341 /*@ 342 TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,X,Xdot)=0 343 344 Collective on TS and Vec 345 346 Input Parameters: 347 + ts - the TS context 348 . t - current time 349 . X - state vector 350 . Xdot - time derivative of state vector 351 - imex - flag indicates if the method is IMEX so that the RHSFunction should be kept separate 352 353 Output Parameter: 354 . Y - right hand side 355 356 Note: 357 Most users should not need to explicitly call this routine, as it 358 is used internally within the nonlinear solvers. 359 360 If the user did did not write their equations in implicit form, this 361 function recasts them in implicit form. 362 363 Level: developer 364 365 .keywords: TS, compute 366 367 .seealso: TSSetIFunction(), TSComputeRHSFunction() 368 @*/ 369 PetscErrorCode TSComputeIFunction(TS ts,PetscReal t,Vec X,Vec Xdot,Vec Y,PetscBool imex) 370 { 371 PetscErrorCode ierr; 372 373 PetscFunctionBegin; 374 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 375 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 376 PetscValidHeaderSpecific(Xdot,VEC_CLASSID,4); 377 PetscValidHeaderSpecific(Y,VEC_CLASSID,5); 378 379 if (!ts->userops->rhsfunction && !ts->userops->ifunction) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 380 381 ierr = PetscLogEventBegin(TS_FunctionEval,ts,X,Xdot,Y);CHKERRQ(ierr); 382 if (ts->userops->ifunction) { 383 PetscStackPush("TS user implicit function"); 384 ierr = (*ts->userops->ifunction)(ts,t,X,Xdot,Y,ts->funP);CHKERRQ(ierr); 385 PetscStackPop; 386 } 387 if (imex) { 388 if (!ts->userops->ifunction) {ierr = VecCopy(Xdot,Y);CHKERRQ(ierr);} 389 } else { 390 if (!ts->userops->ifunction) { 391 ierr = TSComputeRHSFunction(ts,t,X,Y);CHKERRQ(ierr); 392 ierr = VecAYPX(Y,-1,Xdot);CHKERRQ(ierr); 393 } else { 394 Vec Frhs; 395 ierr = TSGetRHSVec_Private(ts,&Frhs);CHKERRQ(ierr); 396 ierr = TSComputeRHSFunction(ts,t,X,Frhs);CHKERRQ(ierr); 397 ierr = VecAXPY(Y,-1,Frhs);CHKERRQ(ierr); 398 } 399 } 400 ierr = PetscLogEventEnd(TS_FunctionEval,ts,X,Xdot,Y);CHKERRQ(ierr); 401 PetscFunctionReturn(0); 402 } 403 404 #undef __FUNCT__ 405 #define __FUNCT__ "TSComputeIJacobian" 406 /*@ 407 TSComputeIJacobian - Evaluates the Jacobian of the DAE 408 409 Collective on TS and Vec 410 411 Input 412 Input Parameters: 413 + ts - the TS context 414 . t - current timestep 415 . X - state vector 416 . Xdot - time derivative of state vector 417 . shift - shift to apply, see note below 418 - imex - flag indicates if the method is IMEX so that the RHSJacobian should be kept separate 419 420 Output Parameters: 421 + A - Jacobian matrix 422 . B - optional preconditioning matrix 423 - flag - flag indicating matrix structure 424 425 Notes: 426 If F(t,X,Xdot)=0 is the DAE, the required Jacobian is 427 428 dF/dX + shift*dF/dXdot 429 430 Most users should not need to explicitly call this routine, as it 431 is used internally within the nonlinear solvers. 432 433 Level: developer 434 435 .keywords: TS, compute, Jacobian, matrix 436 437 .seealso: TSSetIJacobian() 438 @*/ 439 PetscErrorCode TSComputeIJacobian(TS ts,PetscReal t,Vec X,Vec Xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,PetscBool imex) 440 { 441 PetscInt Xstate, Xdotstate; 442 PetscErrorCode ierr; 443 444 PetscFunctionBegin; 445 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 446 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 447 PetscValidHeaderSpecific(Xdot,VEC_CLASSID,4); 448 PetscValidPointer(A,6); 449 PetscValidHeaderSpecific(*A,MAT_CLASSID,6); 450 PetscValidPointer(B,7); 451 PetscValidHeaderSpecific(*B,MAT_CLASSID,7); 452 PetscValidPointer(flg,8); 453 ierr = PetscObjectStateQuery((PetscObject)X,&Xstate);CHKERRQ(ierr); 454 ierr = PetscObjectStateQuery((PetscObject)Xdot,&Xdotstate);CHKERRQ(ierr); 455 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))) { 456 *flg = ts->ijacobian.mstructure; 457 ierr = MatScale(*A, shift / ts->ijacobian.shift);CHKERRQ(ierr); 458 PetscFunctionReturn(0); 459 } 460 461 if (!ts->userops->rhsjacobian && !ts->userops->ijacobian) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()"); 462 463 *flg = SAME_NONZERO_PATTERN; /* In case we're solving a linear problem in which case it wouldn't get initialized below. */ 464 ierr = PetscLogEventBegin(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr); 465 if (ts->userops->ijacobian) { 466 PetscStackPush("TS user implicit Jacobian"); 467 ierr = (*ts->userops->ijacobian)(ts,t,X,Xdot,shift,A,B,flg,ts->jacP);CHKERRQ(ierr); 468 PetscStackPop; 469 /* make sure user returned a correct Jacobian and preconditioner */ 470 PetscValidHeaderSpecific(*A,MAT_CLASSID,4); 471 PetscValidHeaderSpecific(*B,MAT_CLASSID,5); 472 } 473 if (imex) { 474 if (!ts->userops->ijacobian) { /* system was written as Xdot = F(t,X) */ 475 ierr = MatZeroEntries(*A);CHKERRQ(ierr); 476 ierr = MatShift(*A,1.0);CHKERRQ(ierr); 477 if (*A != *B) { 478 ierr = MatZeroEntries(*B);CHKERRQ(ierr); 479 ierr = MatShift(*B,shift);CHKERRQ(ierr); 480 } 481 *flg = SAME_PRECONDITIONER; 482 } 483 } else { 484 if (!ts->userops->ijacobian) { 485 ierr = TSComputeRHSJacobian(ts,t,X,A,B,flg);CHKERRQ(ierr); 486 ierr = MatScale(*A,-1);CHKERRQ(ierr); 487 ierr = MatShift(*A,shift);CHKERRQ(ierr); 488 if (*A != *B) { 489 ierr = MatScale(*B,-1);CHKERRQ(ierr); 490 ierr = MatShift(*B,shift);CHKERRQ(ierr); 491 } 492 } else if (ts->userops->rhsjacobian) { 493 Mat Arhs,Brhs; 494 MatStructure axpy,flg2 = DIFFERENT_NONZERO_PATTERN; 495 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 496 ierr = TSComputeRHSJacobian(ts,t,X,&Arhs,&Brhs,&flg2);CHKERRQ(ierr); 497 axpy = (*flg == flg2) ? SAME_NONZERO_PATTERN : DIFFERENT_NONZERO_PATTERN; 498 ierr = MatAXPY(*A,-1,Arhs,axpy);CHKERRQ(ierr); 499 if (*A != *B) { 500 ierr = MatAXPY(*B,-1,Brhs,axpy);CHKERRQ(ierr); 501 } 502 *flg = PetscMin(*flg,flg2); 503 } 504 } 505 506 ts->ijacobian.time = t; 507 ts->ijacobian.X = X; 508 ts->ijacobian.Xdot = Xdot; 509 ierr = PetscObjectStateQuery((PetscObject)X,&ts->ijacobian.Xstate);CHKERRQ(ierr); 510 ierr = PetscObjectStateQuery((PetscObject)Xdot,&ts->ijacobian.Xdotstate);CHKERRQ(ierr); 511 ts->ijacobian.shift = shift; 512 ts->ijacobian.imex = imex; 513 ts->ijacobian.mstructure = *flg; 514 ierr = PetscLogEventEnd(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr); 515 PetscFunctionReturn(0); 516 } 517 518 #undef __FUNCT__ 519 #define __FUNCT__ "TSSetRHSFunction" 520 /*@C 521 TSSetRHSFunction - Sets the routine for evaluating the function, 522 F(t,u), where U_t = F(t,u). 523 524 Logically Collective on TS 525 526 Input Parameters: 527 + ts - the TS context obtained from TSCreate() 528 . r - vector to put the computed right hand side (or PETSC_NULL to have it created) 529 . f - routine for evaluating the right-hand-side function 530 - ctx - [optional] user-defined context for private data for the 531 function evaluation routine (may be PETSC_NULL) 532 533 Calling sequence of func: 534 $ func (TS ts,PetscReal t,Vec u,Vec F,void *ctx); 535 536 + t - current timestep 537 . u - input vector 538 . F - function vector 539 - ctx - [optional] user-defined function context 540 541 Important: 542 The user MUST call either this routine or TSSetMatrices(). 543 544 Level: beginner 545 546 .keywords: TS, timestep, set, right-hand-side, function 547 548 .seealso: TSSetMatrices() 549 @*/ 550 PetscErrorCode TSSetRHSFunction(TS ts,Vec r,PetscErrorCode (*f)(TS,PetscReal,Vec,Vec,void*),void *ctx) 551 { 552 PetscErrorCode ierr; 553 SNES snes; 554 555 PetscFunctionBegin; 556 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 557 if (r) PetscValidHeaderSpecific(r,VEC_CLASSID,2); 558 if (f) ts->userops->rhsfunction = f; 559 if (ctx) ts->funP = ctx; 560 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 561 ierr = SNESSetFunction(snes,r,SNESTSFormFunction,ts);CHKERRQ(ierr); 562 PetscFunctionReturn(0); 563 } 564 565 #undef __FUNCT__ 566 #define __FUNCT__ "TSSetRHSJacobian" 567 /*@C 568 TSSetRHSJacobian - Sets the function to compute the Jacobian of F, 569 where U_t = F(U,t), as well as the location to store the matrix. 570 Use TSSetMatrices() for linear problems. 571 572 Logically Collective on TS 573 574 Input Parameters: 575 + ts - the TS context obtained from TSCreate() 576 . A - Jacobian matrix 577 . B - preconditioner matrix (usually same as A) 578 . f - the Jacobian evaluation routine 579 - ctx - [optional] user-defined context for private data for the 580 Jacobian evaluation routine (may be PETSC_NULL) 581 582 Calling sequence of func: 583 $ func (TS ts,PetscReal t,Vec u,Mat *A,Mat *B,MatStructure *flag,void *ctx); 584 585 + t - current timestep 586 . u - input vector 587 . A - matrix A, where U_t = A(t)u 588 . B - preconditioner matrix, usually the same as A 589 . flag - flag indicating information about the preconditioner matrix 590 structure (same as flag in KSPSetOperators()) 591 - ctx - [optional] user-defined context for matrix evaluation routine 592 593 Notes: 594 See KSPSetOperators() for important information about setting the flag 595 output parameter in the routine func(). Be sure to read this information! 596 597 The routine func() takes Mat * as the matrix arguments rather than Mat. 598 This allows the matrix evaluation routine to replace A and/or B with a 599 completely new matrix structure (not just different matrix elements) 600 when appropriate, for instance, if the nonzero structure is changing 601 throughout the global iterations. 602 603 Level: beginner 604 605 .keywords: TS, timestep, set, right-hand-side, Jacobian 606 607 .seealso: TSDefaultComputeJacobianColor(), 608 SNESDefaultComputeJacobianColor(), TSSetRHSFunction(), TSSetMatrices() 609 610 @*/ 611 PetscErrorCode TSSetRHSJacobian(TS ts,Mat A,Mat B,TSRHSJacobian f,void *ctx) 612 { 613 PetscErrorCode ierr; 614 SNES snes; 615 616 PetscFunctionBegin; 617 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 618 if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 619 if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 620 if (A) PetscCheckSameComm(ts,1,A,2); 621 if (B) PetscCheckSameComm(ts,1,B,3); 622 623 if (f) ts->userops->rhsjacobian = f; 624 if (ctx) ts->jacP = ctx; 625 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 626 if (!ts->userops->ijacobian) { 627 ierr = SNESSetJacobian(snes,A,B,SNESTSFormJacobian,ts);CHKERRQ(ierr); 628 } 629 if (A) { 630 ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 631 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 632 ts->Arhs = A; 633 } 634 if (B) { 635 ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 636 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 637 ts->Brhs = B; 638 } 639 PetscFunctionReturn(0); 640 } 641 642 643 #undef __FUNCT__ 644 #define __FUNCT__ "TSSetIFunction" 645 /*@C 646 TSSetIFunction - Set the function to compute F(t,U,U_t) where F = 0 is the DAE to be solved. 647 648 Logically Collective on TS 649 650 Input Parameters: 651 + ts - the TS context obtained from TSCreate() 652 . r - vector to hold the residual (or PETSC_NULL to have it created internally) 653 . f - the function evaluation routine 654 - ctx - user-defined context for private data for the function evaluation routine (may be PETSC_NULL) 655 656 Calling sequence of f: 657 $ f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx); 658 659 + t - time at step/stage being solved 660 . u - state vector 661 . u_t - time derivative of state vector 662 . F - function vector 663 - ctx - [optional] user-defined context for matrix evaluation routine 664 665 Important: 666 The user MUST call either this routine, TSSetRHSFunction(), or TSSetMatrices(). This routine must be used when not solving an ODE. 667 668 Level: beginner 669 670 .keywords: TS, timestep, set, DAE, Jacobian 671 672 .seealso: TSSetMatrices(), TSSetRHSFunction(), TSSetIJacobian() 673 @*/ 674 PetscErrorCode TSSetIFunction(TS ts,Vec res,TSIFunction f,void *ctx) 675 { 676 PetscErrorCode ierr; 677 SNES snes; 678 679 PetscFunctionBegin; 680 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 681 if (res) PetscValidHeaderSpecific(res,VEC_CLASSID,2); 682 if (f) ts->userops->ifunction = f; 683 if (ctx) ts->funP = ctx; 684 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 685 ierr = SNESSetFunction(snes,res,SNESTSFormFunction,ts);CHKERRQ(ierr); 686 PetscFunctionReturn(0); 687 } 688 689 #undef __FUNCT__ 690 #define __FUNCT__ "TSGetIFunction" 691 /*@C 692 TSGetIFunction - Returns the vector where the implicit residual is stored and the function/contex to compute it. 693 694 Not Collective 695 696 Input Parameter: 697 . ts - the TS context 698 699 Output Parameter: 700 + r - vector to hold residual (or PETSC_NULL) 701 . func - the function to compute residual (or PETSC_NULL) 702 - ctx - the function context (or PETSC_NULL) 703 704 Level: advanced 705 706 .keywords: TS, nonlinear, get, function 707 708 .seealso: TSSetIFunction(), SNESGetFunction() 709 @*/ 710 PetscErrorCode TSGetIFunction(TS ts,Vec *r,TSIFunction *func,void **ctx) 711 { 712 PetscErrorCode ierr; 713 SNES snes; 714 715 PetscFunctionBegin; 716 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 717 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 718 ierr = SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 719 if (func) *func = ts->userops->ifunction; 720 if (ctx) *ctx = ts->funP; 721 PetscFunctionReturn(0); 722 } 723 724 #undef __FUNCT__ 725 #define __FUNCT__ "TSGetRHSFunction" 726 /*@C 727 TSGetRHSFunction - Returns the vector where the right hand side is stored and the function/context to compute it. 728 729 Not Collective 730 731 Input Parameter: 732 . ts - the TS context 733 734 Output Parameter: 735 + r - vector to hold computed right hand side (or PETSC_NULL) 736 . func - the function to compute right hand side (or PETSC_NULL) 737 - ctx - the function context (or PETSC_NULL) 738 739 Level: advanced 740 741 .keywords: TS, nonlinear, get, function 742 743 .seealso: TSSetRhsfunction(), SNESGetFunction() 744 @*/ 745 PetscErrorCode TSGetRHSFunction(TS ts,Vec *r,TSRHSFunction *func,void **ctx) 746 { 747 PetscErrorCode ierr; 748 SNES snes; 749 750 PetscFunctionBegin; 751 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 752 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 753 ierr = SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 754 if (func) *func = ts->userops->rhsfunction; 755 if (ctx) *ctx = ts->funP; 756 PetscFunctionReturn(0); 757 } 758 759 #undef __FUNCT__ 760 #define __FUNCT__ "TSSetIJacobian" 761 /*@C 762 TSSetIJacobian - Set the function to compute the matrix dF/dU + a*dF/dU_t where F(t,U,U_t) is the function 763 you provided with TSSetIFunction(). 764 765 Logically Collective on TS 766 767 Input Parameters: 768 + ts - the TS context obtained from TSCreate() 769 . A - Jacobian matrix 770 . B - preconditioning matrix for A (may be same as A) 771 . f - the Jacobian evaluation routine 772 - ctx - user-defined context for private data for the Jacobian evaluation routine (may be PETSC_NULL) 773 774 Calling sequence of f: 775 $ f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat *A,Mat *B,MatStructure *flag,void *ctx); 776 777 + t - time at step/stage being solved 778 . U - state vector 779 . U_t - time derivative of state vector 780 . a - shift 781 . A - Jacobian of G(U) = F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t 782 . B - preconditioning matrix for A, may be same as A 783 . flag - flag indicating information about the preconditioner matrix 784 structure (same as flag in KSPSetOperators()) 785 - ctx - [optional] user-defined context for matrix evaluation routine 786 787 Notes: 788 The matrices A and B are exactly the matrices that are used by SNES for the nonlinear solve. 789 790 The matrix dF/dU + a*dF/dU_t you provide turns out to be 791 the Jacobian of G(U) = F(t,U,W+a*U) where F(t,U,U_t) = 0 is the DAE to be solved. 792 The time integrator internally approximates U_t by W+a*U where the positive "shift" 793 a and vector W depend on the integration method, step size, and past states. For example with 794 the backward Euler method a = 1/dt and W = -a*U(previous timestep) so 795 W + a*U = a*(U - U(previous timestep)) = (U - U(previous timestep))/dt 796 797 Level: beginner 798 799 .keywords: TS, timestep, DAE, Jacobian 800 801 .seealso: TSSetIFunction(), TSSetRHSJacobian() 802 803 @*/ 804 PetscErrorCode TSSetIJacobian(TS ts,Mat A,Mat B,TSIJacobian f,void *ctx) 805 { 806 PetscErrorCode ierr; 807 SNES snes; 808 809 PetscFunctionBegin; 810 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 811 if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 812 if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 813 if (A) PetscCheckSameComm(ts,1,A,2); 814 if (B) PetscCheckSameComm(ts,1,B,3); 815 if (f) ts->userops->ijacobian = f; 816 if (ctx) ts->jacP = ctx; 817 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 818 ierr = SNESSetJacobian(snes,A,B,SNESTSFormJacobian,ts);CHKERRQ(ierr); 819 PetscFunctionReturn(0); 820 } 821 822 #undef __FUNCT__ 823 #define __FUNCT__ "TSView" 824 /*@C 825 TSView - Prints the TS data structure. 826 827 Collective on TS 828 829 Input Parameters: 830 + ts - the TS context obtained from TSCreate() 831 - viewer - visualization context 832 833 Options Database Key: 834 . -ts_view - calls TSView() at end of TSStep() 835 836 Notes: 837 The available visualization contexts include 838 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 839 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 840 output where only the first processor opens 841 the file. All other processors send their 842 data to the first processor to print. 843 844 The user can open an alternative visualization context with 845 PetscViewerASCIIOpen() - output to a specified file. 846 847 Level: beginner 848 849 .keywords: TS, timestep, view 850 851 .seealso: PetscViewerASCIIOpen() 852 @*/ 853 PetscErrorCode TSView(TS ts,PetscViewer viewer) 854 { 855 PetscErrorCode ierr; 856 const TSType type; 857 PetscBool iascii,isstring,isundials; 858 859 PetscFunctionBegin; 860 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 861 if (!viewer) { 862 ierr = PetscViewerASCIIGetStdout(((PetscObject)ts)->comm,&viewer);CHKERRQ(ierr); 863 } 864 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 865 PetscCheckSameComm(ts,1,viewer,2); 866 867 ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 868 ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 869 if (iascii) { 870 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ts,viewer,"TS Object");CHKERRQ(ierr); 871 if (ts->ops->view) { 872 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 873 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 874 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 875 } 876 ierr = PetscViewerASCIIPrintf(viewer," maximum steps=%D\n",ts->max_steps);CHKERRQ(ierr); 877 ierr = PetscViewerASCIIPrintf(viewer," maximum time=%G\n",ts->max_time);CHKERRQ(ierr); 878 if (ts->problem_type == TS_NONLINEAR) { 879 ierr = PetscViewerASCIIPrintf(viewer," total number of nonlinear solver iterations=%D\n",ts->nonlinear_its);CHKERRQ(ierr); 880 ierr = PetscViewerASCIIPrintf(viewer," total number of nonlinear solve failures=%D\n",ts->max_snes_failures);CHKERRQ(ierr); 881 } 882 ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",ts->linear_its);CHKERRQ(ierr); 883 ierr = PetscViewerASCIIPrintf(viewer," total number of rejected steps=%D\n",ts->reject);CHKERRQ(ierr); 884 } else if (isstring) { 885 ierr = TSGetType(ts,&type);CHKERRQ(ierr); 886 ierr = PetscViewerStringSPrintf(viewer," %-7.7s",type);CHKERRQ(ierr); 887 } 888 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 889 ierr = PetscTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials);CHKERRQ(ierr); 890 if (!isundials && ts->snes) {ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr);} 891 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 892 PetscFunctionReturn(0); 893 } 894 895 896 #undef __FUNCT__ 897 #define __FUNCT__ "TSSetApplicationContext" 898 /*@ 899 TSSetApplicationContext - Sets an optional user-defined context for 900 the timesteppers. 901 902 Logically Collective on TS 903 904 Input Parameters: 905 + ts - the TS context obtained from TSCreate() 906 - usrP - optional user context 907 908 Level: intermediate 909 910 .keywords: TS, timestep, set, application, context 911 912 .seealso: TSGetApplicationContext() 913 @*/ 914 PetscErrorCode TSSetApplicationContext(TS ts,void *usrP) 915 { 916 PetscFunctionBegin; 917 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 918 ts->user = usrP; 919 PetscFunctionReturn(0); 920 } 921 922 #undef __FUNCT__ 923 #define __FUNCT__ "TSGetApplicationContext" 924 /*@ 925 TSGetApplicationContext - Gets the user-defined context for the 926 timestepper. 927 928 Not Collective 929 930 Input Parameter: 931 . ts - the TS context obtained from TSCreate() 932 933 Output Parameter: 934 . usrP - user context 935 936 Level: intermediate 937 938 .keywords: TS, timestep, get, application, context 939 940 .seealso: TSSetApplicationContext() 941 @*/ 942 PetscErrorCode TSGetApplicationContext(TS ts,void *usrP) 943 { 944 PetscFunctionBegin; 945 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 946 *(void**)usrP = ts->user; 947 PetscFunctionReturn(0); 948 } 949 950 #undef __FUNCT__ 951 #define __FUNCT__ "TSGetTimeStepNumber" 952 /*@ 953 TSGetTimeStepNumber - Gets the current number of timesteps. 954 955 Not Collective 956 957 Input Parameter: 958 . ts - the TS context obtained from TSCreate() 959 960 Output Parameter: 961 . iter - number steps so far 962 963 Level: intermediate 964 965 .keywords: TS, timestep, get, iteration, number 966 @*/ 967 PetscErrorCode TSGetTimeStepNumber(TS ts,PetscInt* iter) 968 { 969 PetscFunctionBegin; 970 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 971 PetscValidIntPointer(iter,2); 972 *iter = ts->steps; 973 PetscFunctionReturn(0); 974 } 975 976 #undef __FUNCT__ 977 #define __FUNCT__ "TSSetInitialTimeStep" 978 /*@ 979 TSSetInitialTimeStep - Sets the initial timestep to be used, 980 as well as the initial time. 981 982 Logically Collective on TS 983 984 Input Parameters: 985 + ts - the TS context obtained from TSCreate() 986 . initial_time - the initial time 987 - time_step - the size of the timestep 988 989 Level: intermediate 990 991 .seealso: TSSetTimeStep(), TSGetTimeStep() 992 993 .keywords: TS, set, initial, timestep 994 @*/ 995 PetscErrorCode TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step) 996 { 997 PetscErrorCode ierr; 998 999 PetscFunctionBegin; 1000 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1001 ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr); 1002 ts->initial_time_step = time_step; 1003 ts->ptime = initial_time; 1004 PetscFunctionReturn(0); 1005 } 1006 1007 #undef __FUNCT__ 1008 #define __FUNCT__ "TSSetTimeStep" 1009 /*@ 1010 TSSetTimeStep - Allows one to reset the timestep at any time, 1011 useful for simple pseudo-timestepping codes. 1012 1013 Logically Collective on TS 1014 1015 Input Parameters: 1016 + ts - the TS context obtained from TSCreate() 1017 - time_step - the size of the timestep 1018 1019 Level: intermediate 1020 1021 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 1022 1023 .keywords: TS, set, timestep 1024 @*/ 1025 PetscErrorCode TSSetTimeStep(TS ts,PetscReal time_step) 1026 { 1027 PetscFunctionBegin; 1028 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1029 PetscValidLogicalCollectiveReal(ts,time_step,2); 1030 ts->time_step = time_step; 1031 ts->next_time_step = time_step; 1032 PetscFunctionReturn(0); 1033 } 1034 1035 #undef __FUNCT__ 1036 #define __FUNCT__ "TSGetTimeStep" 1037 /*@ 1038 TSGetTimeStep - Gets the current timestep size. 1039 1040 Not Collective 1041 1042 Input Parameter: 1043 . ts - the TS context obtained from TSCreate() 1044 1045 Output Parameter: 1046 . dt - the current timestep size 1047 1048 Level: intermediate 1049 1050 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 1051 1052 .keywords: TS, get, timestep 1053 @*/ 1054 PetscErrorCode TSGetTimeStep(TS ts,PetscReal* dt) 1055 { 1056 PetscFunctionBegin; 1057 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1058 PetscValidDoublePointer(dt,2); 1059 *dt = ts->time_step; 1060 PetscFunctionReturn(0); 1061 } 1062 1063 #undef __FUNCT__ 1064 #define __FUNCT__ "TSGetSolution" 1065 /*@ 1066 TSGetSolution - Returns the solution at the present timestep. It 1067 is valid to call this routine inside the function that you are evaluating 1068 in order to move to the new timestep. This vector not changed until 1069 the solution at the next timestep has been calculated. 1070 1071 Not Collective, but Vec returned is parallel if TS is parallel 1072 1073 Input Parameter: 1074 . ts - the TS context obtained from TSCreate() 1075 1076 Output Parameter: 1077 . v - the vector containing the solution 1078 1079 Level: intermediate 1080 1081 .seealso: TSGetTimeStep() 1082 1083 .keywords: TS, timestep, get, solution 1084 @*/ 1085 PetscErrorCode TSGetSolution(TS ts,Vec *v) 1086 { 1087 PetscFunctionBegin; 1088 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1089 PetscValidPointer(v,2); 1090 *v = ts->vec_sol; 1091 PetscFunctionReturn(0); 1092 } 1093 1094 /* ----- Routines to initialize and destroy a timestepper ---- */ 1095 #undef __FUNCT__ 1096 #define __FUNCT__ "TSSetProblemType" 1097 /*@ 1098 TSSetProblemType - Sets the type of problem to be solved. 1099 1100 Not collective 1101 1102 Input Parameters: 1103 + ts - The TS 1104 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 1105 .vb 1106 U_t = A U 1107 U_t = A(t) U 1108 U_t = F(t,U) 1109 .ve 1110 1111 Level: beginner 1112 1113 .keywords: TS, problem type 1114 .seealso: TSSetUp(), TSProblemType, TS 1115 @*/ 1116 PetscErrorCode TSSetProblemType(TS ts, TSProblemType type) 1117 { 1118 PetscErrorCode ierr; 1119 1120 PetscFunctionBegin; 1121 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1122 ts->problem_type = type; 1123 if (type == TS_LINEAR) { 1124 SNES snes; 1125 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1126 ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr); 1127 } 1128 PetscFunctionReturn(0); 1129 } 1130 1131 #undef __FUNCT__ 1132 #define __FUNCT__ "TSGetProblemType" 1133 /*@C 1134 TSGetProblemType - Gets the type of problem to be solved. 1135 1136 Not collective 1137 1138 Input Parameter: 1139 . ts - The TS 1140 1141 Output Parameter: 1142 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 1143 .vb 1144 M U_t = A U 1145 M(t) U_t = A(t) U 1146 U_t = F(t,U) 1147 .ve 1148 1149 Level: beginner 1150 1151 .keywords: TS, problem type 1152 .seealso: TSSetUp(), TSProblemType, TS 1153 @*/ 1154 PetscErrorCode TSGetProblemType(TS ts, TSProblemType *type) 1155 { 1156 PetscFunctionBegin; 1157 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1158 PetscValidIntPointer(type,2); 1159 *type = ts->problem_type; 1160 PetscFunctionReturn(0); 1161 } 1162 1163 #undef __FUNCT__ 1164 #define __FUNCT__ "TSSetUp" 1165 /*@ 1166 TSSetUp - Sets up the internal data structures for the later use 1167 of a timestepper. 1168 1169 Collective on TS 1170 1171 Input Parameter: 1172 . ts - the TS context obtained from TSCreate() 1173 1174 Notes: 1175 For basic use of the TS solvers the user need not explicitly call 1176 TSSetUp(), since these actions will automatically occur during 1177 the call to TSStep(). However, if one wishes to control this 1178 phase separately, TSSetUp() should be called after TSCreate() 1179 and optional routines of the form TSSetXXX(), but before TSStep(). 1180 1181 Level: advanced 1182 1183 .keywords: TS, timestep, setup 1184 1185 .seealso: TSCreate(), TSStep(), TSDestroy() 1186 @*/ 1187 PetscErrorCode TSSetUp(TS ts) 1188 { 1189 PetscErrorCode ierr; 1190 1191 PetscFunctionBegin; 1192 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1193 if (ts->setupcalled) PetscFunctionReturn(0); 1194 1195 if (!((PetscObject)ts)->type_name) { 1196 ierr = TSSetType(ts,TSEULER);CHKERRQ(ierr); 1197 } 1198 1199 if (!ts->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first"); 1200 1201 if (ts->ops->setup) { 1202 ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr); 1203 } 1204 1205 ts->setupcalled = PETSC_TRUE; 1206 PetscFunctionReturn(0); 1207 } 1208 1209 #undef __FUNCT__ 1210 #define __FUNCT__ "TSReset" 1211 /*@ 1212 TSReset - Resets a TS context and removes any allocated Vecs and Mats. 1213 1214 Collective on TS 1215 1216 Input Parameter: 1217 . ts - the TS context obtained from TSCreate() 1218 1219 Level: beginner 1220 1221 .keywords: TS, timestep, reset 1222 1223 .seealso: TSCreate(), TSSetup(), TSDestroy() 1224 @*/ 1225 PetscErrorCode TSReset(TS ts) 1226 { 1227 PetscErrorCode ierr; 1228 1229 PetscFunctionBegin; 1230 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1231 if (ts->ops->reset) { 1232 ierr = (*ts->ops->reset)(ts);CHKERRQ(ierr); 1233 } 1234 if (ts->snes) {ierr = SNESReset(ts->snes);CHKERRQ(ierr);} 1235 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 1236 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 1237 ierr = VecDestroy(&ts->Frhs);CHKERRQ(ierr); 1238 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 1239 if (ts->work) {ierr = VecDestroyVecs(ts->nwork,&ts->work);CHKERRQ(ierr);} 1240 ts->setupcalled = PETSC_FALSE; 1241 PetscFunctionReturn(0); 1242 } 1243 1244 #undef __FUNCT__ 1245 #define __FUNCT__ "TSDestroy" 1246 /*@ 1247 TSDestroy - Destroys the timestepper context that was created 1248 with TSCreate(). 1249 1250 Collective on TS 1251 1252 Input Parameter: 1253 . ts - the TS context obtained from TSCreate() 1254 1255 Level: beginner 1256 1257 .keywords: TS, timestepper, destroy 1258 1259 .seealso: TSCreate(), TSSetUp(), TSSolve() 1260 @*/ 1261 PetscErrorCode TSDestroy(TS *ts) 1262 { 1263 PetscErrorCode ierr; 1264 1265 PetscFunctionBegin; 1266 if (!*ts) PetscFunctionReturn(0); 1267 PetscValidHeaderSpecific((*ts),TS_CLASSID,1); 1268 if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; PetscFunctionReturn(0);} 1269 1270 ierr = TSReset((*ts));CHKERRQ(ierr); 1271 1272 /* if memory was published with AMS then destroy it */ 1273 ierr = PetscObjectDepublish((*ts));CHKERRQ(ierr); 1274 if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);} 1275 1276 ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr); 1277 ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr); 1278 ierr = TSMonitorCancel((*ts));CHKERRQ(ierr); 1279 1280 ierr = PetscFree((*ts)->userops); 1281 1282 ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr); 1283 PetscFunctionReturn(0); 1284 } 1285 1286 #undef __FUNCT__ 1287 #define __FUNCT__ "TSGetSNES" 1288 /*@ 1289 TSGetSNES - Returns the SNES (nonlinear solver) associated with 1290 a TS (timestepper) context. Valid only for nonlinear problems. 1291 1292 Not Collective, but SNES is parallel if TS is parallel 1293 1294 Input Parameter: 1295 . ts - the TS context obtained from TSCreate() 1296 1297 Output Parameter: 1298 . snes - the nonlinear solver context 1299 1300 Notes: 1301 The user can then directly manipulate the SNES context to set various 1302 options, etc. Likewise, the user can then extract and manipulate the 1303 KSP, KSP, and PC contexts as well. 1304 1305 TSGetSNES() does not work for integrators that do not use SNES; in 1306 this case TSGetSNES() returns PETSC_NULL in snes. 1307 1308 Level: beginner 1309 1310 .keywords: timestep, get, SNES 1311 @*/ 1312 PetscErrorCode TSGetSNES(TS ts,SNES *snes) 1313 { 1314 PetscErrorCode ierr; 1315 1316 PetscFunctionBegin; 1317 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1318 PetscValidPointer(snes,2); 1319 if (!ts->snes) { 1320 ierr = SNESCreate(((PetscObject)ts)->comm,&ts->snes);CHKERRQ(ierr); 1321 ierr = PetscLogObjectParent(ts,ts->snes);CHKERRQ(ierr); 1322 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr); 1323 if (ts->problem_type == TS_LINEAR) { 1324 ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr); 1325 } 1326 } 1327 *snes = ts->snes; 1328 PetscFunctionReturn(0); 1329 } 1330 1331 #undef __FUNCT__ 1332 #define __FUNCT__ "TSGetKSP" 1333 /*@ 1334 TSGetKSP - Returns the KSP (linear solver) associated with 1335 a TS (timestepper) context. 1336 1337 Not Collective, but KSP is parallel if TS is parallel 1338 1339 Input Parameter: 1340 . ts - the TS context obtained from TSCreate() 1341 1342 Output Parameter: 1343 . ksp - the nonlinear solver context 1344 1345 Notes: 1346 The user can then directly manipulate the KSP context to set various 1347 options, etc. Likewise, the user can then extract and manipulate the 1348 KSP and PC contexts as well. 1349 1350 TSGetKSP() does not work for integrators that do not use KSP; 1351 in this case TSGetKSP() returns PETSC_NULL in ksp. 1352 1353 Level: beginner 1354 1355 .keywords: timestep, get, KSP 1356 @*/ 1357 PetscErrorCode TSGetKSP(TS ts,KSP *ksp) 1358 { 1359 PetscErrorCode ierr; 1360 SNES snes; 1361 1362 PetscFunctionBegin; 1363 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1364 PetscValidPointer(ksp,2); 1365 if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first"); 1366 if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()"); 1367 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1368 ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr); 1369 PetscFunctionReturn(0); 1370 } 1371 1372 /* ----------- Routines to set solver parameters ---------- */ 1373 1374 #undef __FUNCT__ 1375 #define __FUNCT__ "TSGetDuration" 1376 /*@ 1377 TSGetDuration - Gets the maximum number of timesteps to use and 1378 maximum time for iteration. 1379 1380 Not Collective 1381 1382 Input Parameters: 1383 + ts - the TS context obtained from TSCreate() 1384 . maxsteps - maximum number of iterations to use, or PETSC_NULL 1385 - maxtime - final time to iterate to, or PETSC_NULL 1386 1387 Level: intermediate 1388 1389 .keywords: TS, timestep, get, maximum, iterations, time 1390 @*/ 1391 PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime) 1392 { 1393 PetscFunctionBegin; 1394 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1395 if (maxsteps) { 1396 PetscValidIntPointer(maxsteps,2); 1397 *maxsteps = ts->max_steps; 1398 } 1399 if (maxtime ) { 1400 PetscValidScalarPointer(maxtime,3); 1401 *maxtime = ts->max_time; 1402 } 1403 PetscFunctionReturn(0); 1404 } 1405 1406 #undef __FUNCT__ 1407 #define __FUNCT__ "TSSetDuration" 1408 /*@ 1409 TSSetDuration - Sets the maximum number of timesteps to use and 1410 maximum time for iteration. 1411 1412 Logically Collective on TS 1413 1414 Input Parameters: 1415 + ts - the TS context obtained from TSCreate() 1416 . maxsteps - maximum number of iterations to use 1417 - maxtime - final time to iterate to 1418 1419 Options Database Keys: 1420 . -ts_max_steps <maxsteps> - Sets maxsteps 1421 . -ts_max_time <maxtime> - Sets maxtime 1422 1423 Notes: 1424 The default maximum number of iterations is 5000. Default time is 5.0 1425 1426 Level: intermediate 1427 1428 .keywords: TS, timestep, set, maximum, iterations 1429 @*/ 1430 PetscErrorCode TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime) 1431 { 1432 PetscFunctionBegin; 1433 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1434 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 1435 PetscValidLogicalCollectiveReal(ts,maxtime,2); 1436 if (maxsteps >= 0) ts->max_steps = maxsteps; 1437 if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime; 1438 PetscFunctionReturn(0); 1439 } 1440 1441 #undef __FUNCT__ 1442 #define __FUNCT__ "TSSetSolution" 1443 /*@ 1444 TSSetSolution - Sets the initial solution vector 1445 for use by the TS routines. 1446 1447 Logically Collective on TS and Vec 1448 1449 Input Parameters: 1450 + ts - the TS context obtained from TSCreate() 1451 - x - the solution vector 1452 1453 Level: beginner 1454 1455 .keywords: TS, timestep, set, solution, initial conditions 1456 @*/ 1457 PetscErrorCode TSSetSolution(TS ts,Vec x) 1458 { 1459 PetscErrorCode ierr; 1460 1461 PetscFunctionBegin; 1462 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1463 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1464 ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 1465 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 1466 ts->vec_sol = x; 1467 PetscFunctionReturn(0); 1468 } 1469 1470 #undef __FUNCT__ 1471 #define __FUNCT__ "TSSetPreStep" 1472 /*@C 1473 TSSetPreStep - Sets the general-purpose function 1474 called once at the beginning of each time step. 1475 1476 Logically Collective on TS 1477 1478 Input Parameters: 1479 + ts - The TS context obtained from TSCreate() 1480 - func - The function 1481 1482 Calling sequence of func: 1483 . func (TS ts); 1484 1485 Level: intermediate 1486 1487 .keywords: TS, timestep 1488 @*/ 1489 PetscErrorCode TSSetPreStep(TS ts, PetscErrorCode (*func)(TS)) 1490 { 1491 PetscFunctionBegin; 1492 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1493 ts->ops->prestep = func; 1494 PetscFunctionReturn(0); 1495 } 1496 1497 #undef __FUNCT__ 1498 #define __FUNCT__ "TSPreStep" 1499 /*@C 1500 TSPreStep - Runs the user-defined pre-step function. 1501 1502 Collective on TS 1503 1504 Input Parameters: 1505 . ts - The TS context obtained from TSCreate() 1506 1507 Notes: 1508 TSPreStep() is typically used within time stepping implementations, 1509 so most users would not generally call this routine themselves. 1510 1511 Level: developer 1512 1513 .keywords: TS, timestep 1514 @*/ 1515 PetscErrorCode TSPreStep(TS ts) 1516 { 1517 PetscErrorCode ierr; 1518 1519 PetscFunctionBegin; 1520 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1521 if (ts->ops->prestep) { 1522 PetscStackPush("TS PreStep function"); 1523 ierr = (*ts->ops->prestep)(ts);CHKERRQ(ierr); 1524 PetscStackPop; 1525 } 1526 PetscFunctionReturn(0); 1527 } 1528 1529 #undef __FUNCT__ 1530 #define __FUNCT__ "TSSetPostStep" 1531 /*@C 1532 TSSetPostStep - Sets the general-purpose function 1533 called once at the end of each time step. 1534 1535 Logically Collective on TS 1536 1537 Input Parameters: 1538 + ts - The TS context obtained from TSCreate() 1539 - func - The function 1540 1541 Calling sequence of func: 1542 . func (TS ts); 1543 1544 Level: intermediate 1545 1546 .keywords: TS, timestep 1547 @*/ 1548 PetscErrorCode TSSetPostStep(TS ts, PetscErrorCode (*func)(TS)) 1549 { 1550 PetscFunctionBegin; 1551 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1552 ts->ops->poststep = func; 1553 PetscFunctionReturn(0); 1554 } 1555 1556 #undef __FUNCT__ 1557 #define __FUNCT__ "TSPostStep" 1558 /*@C 1559 TSPostStep - Runs the user-defined post-step function. 1560 1561 Collective on TS 1562 1563 Input Parameters: 1564 . ts - The TS context obtained from TSCreate() 1565 1566 Notes: 1567 TSPostStep() is typically used within time stepping implementations, 1568 so most users would not generally call this routine themselves. 1569 1570 Level: developer 1571 1572 .keywords: TS, timestep 1573 @*/ 1574 PetscErrorCode TSPostStep(TS ts) 1575 { 1576 PetscErrorCode ierr; 1577 1578 PetscFunctionBegin; 1579 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1580 if (ts->ops->poststep) { 1581 PetscStackPush("TS PostStep function"); 1582 ierr = (*ts->ops->poststep)(ts);CHKERRQ(ierr); 1583 PetscStackPop; 1584 } 1585 PetscFunctionReturn(0); 1586 } 1587 1588 /* ------------ Routines to set performance monitoring options ----------- */ 1589 1590 #undef __FUNCT__ 1591 #define __FUNCT__ "TSMonitorSet" 1592 /*@C 1593 TSMonitorSet - Sets an ADDITIONAL function that is to be used at every 1594 timestep to display the iteration's progress. 1595 1596 Logically Collective on TS 1597 1598 Input Parameters: 1599 + ts - the TS context obtained from TSCreate() 1600 . func - monitoring routine 1601 . mctx - [optional] user-defined context for private data for the 1602 monitor routine (use PETSC_NULL if no context is desired) 1603 - monitordestroy - [optional] routine that frees monitor context 1604 (may be PETSC_NULL) 1605 1606 Calling sequence of func: 1607 $ int func(TS ts,PetscInt steps,PetscReal time,Vec x,void *mctx) 1608 1609 + ts - the TS context 1610 . steps - iteration number 1611 . time - current time 1612 . x - current iterate 1613 - mctx - [optional] monitoring context 1614 1615 Notes: 1616 This routine adds an additional monitor to the list of monitors that 1617 already has been loaded. 1618 1619 Fortran notes: Only a single monitor function can be set for each TS object 1620 1621 Level: intermediate 1622 1623 .keywords: TS, timestep, set, monitor 1624 1625 .seealso: TSMonitorDefault(), TSMonitorCancel() 1626 @*/ 1627 PetscErrorCode TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**)) 1628 { 1629 PetscFunctionBegin; 1630 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1631 if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 1632 ts->monitor[ts->numbermonitors] = monitor; 1633 ts->mdestroy[ts->numbermonitors] = mdestroy; 1634 ts->monitorcontext[ts->numbermonitors++] = (void*)mctx; 1635 PetscFunctionReturn(0); 1636 } 1637 1638 #undef __FUNCT__ 1639 #define __FUNCT__ "TSMonitorCancel" 1640 /*@C 1641 TSMonitorCancel - Clears all the monitors that have been set on a time-step object. 1642 1643 Logically Collective on TS 1644 1645 Input Parameters: 1646 . ts - the TS context obtained from TSCreate() 1647 1648 Notes: 1649 There is no way to remove a single, specific monitor. 1650 1651 Level: intermediate 1652 1653 .keywords: TS, timestep, set, monitor 1654 1655 .seealso: TSMonitorDefault(), TSMonitorSet() 1656 @*/ 1657 PetscErrorCode TSMonitorCancel(TS ts) 1658 { 1659 PetscErrorCode ierr; 1660 PetscInt i; 1661 1662 PetscFunctionBegin; 1663 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1664 for (i=0; i<ts->numbermonitors; i++) { 1665 if (ts->mdestroy[i]) { 1666 ierr = (*ts->mdestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr); 1667 } 1668 } 1669 ts->numbermonitors = 0; 1670 PetscFunctionReturn(0); 1671 } 1672 1673 #undef __FUNCT__ 1674 #define __FUNCT__ "TSMonitorDefault" 1675 /*@ 1676 TSMonitorDefault - Sets the Default monitor 1677 1678 Level: intermediate 1679 1680 .keywords: TS, set, monitor 1681 1682 .seealso: TSMonitorDefault(), TSMonitorSet() 1683 @*/ 1684 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,void *dummy) 1685 { 1686 PetscErrorCode ierr; 1687 PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(((PetscObject)ts)->comm); 1688 1689 PetscFunctionBegin; 1690 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 1691 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %G time %G\n",step,ts->time_step,ptime);CHKERRQ(ierr); 1692 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 1693 PetscFunctionReturn(0); 1694 } 1695 1696 #undef __FUNCT__ 1697 #define __FUNCT__ "TSStep" 1698 /*@ 1699 TSStep - Steps the requested number of timesteps. 1700 1701 Collective on TS 1702 1703 Input Parameter: 1704 . ts - the TS context obtained from TSCreate() 1705 1706 Output Parameters: 1707 + steps - number of iterations until termination 1708 - ptime - time until termination 1709 1710 Level: beginner 1711 1712 .keywords: TS, timestep, solve 1713 1714 .seealso: TSCreate(), TSSetUp(), TSDestroy() 1715 @*/ 1716 PetscErrorCode TSStep(TS ts) 1717 { 1718 PetscErrorCode ierr; 1719 1720 PetscFunctionBegin; 1721 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1722 1723 ierr = TSSetUp(ts);CHKERRQ(ierr); 1724 1725 ierr = PetscLogEventBegin(TS_Step, ts, 0, 0, 0);CHKERRQ(ierr); 1726 ierr = (*ts->ops->step)(ts);CHKERRQ(ierr); 1727 ierr = PetscLogEventEnd(TS_Step, ts, 0, 0, 0);CHKERRQ(ierr); 1728 PetscFunctionReturn(0); 1729 } 1730 1731 #undef __FUNCT__ 1732 #define __FUNCT__ "TSSolve" 1733 /*@ 1734 TSSolve - Steps the requested number of timesteps. 1735 1736 Collective on TS 1737 1738 Input Parameter: 1739 + ts - the TS context obtained from TSCreate() 1740 - x - the solution vector, or PETSC_NULL if it was set with TSSetSolution() 1741 1742 Level: beginner 1743 1744 .keywords: TS, timestep, solve 1745 1746 .seealso: TSCreate(), TSSetSolution(), TSStep() 1747 @*/ 1748 PetscErrorCode TSSolve(TS ts, Vec x) 1749 { 1750 PetscInt i; 1751 PetscErrorCode ierr; 1752 1753 PetscFunctionBegin; 1754 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1755 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1756 ierr = TSSetSolution(ts,x); CHKERRQ(ierr); 1757 ierr = TSSetUp(ts); CHKERRQ(ierr); 1758 /* reset time step and iteration counters */ 1759 ts->steps = 0; 1760 ts->linear_its = 0; 1761 ts->nonlinear_its = 0; 1762 ts->reason = TS_CONVERGED_ITERATING; 1763 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 1764 1765 if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */ 1766 ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr); 1767 } else { 1768 i = 0; 1769 if (i >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 1770 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 1771 /* steps the requested number of timesteps. */ 1772 while (!ts->reason) { 1773 ierr = TSPreStep(ts);CHKERRQ(ierr); 1774 ierr = TSStep(ts);CHKERRQ(ierr); 1775 if (ts->reason < 0) { 1776 if (ts->errorifstepfailed) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_NOT_CONVERGED,"TSStep has failed"); 1777 } else if (++i >= ts->max_steps) { 1778 ts->reason = TS_CONVERGED_ITS; 1779 } else if (ts->ptime >= ts->max_time) { 1780 ts->reason = TS_CONVERGED_TIME; 1781 } 1782 ierr = TSPostStep(ts);CHKERRQ(ierr); 1783 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 1784 } 1785 } 1786 if (!PetscPreLoadingOn) { 1787 ierr = TSViewFromOptions(ts,((PetscObject)ts)->name);CHKERRQ(ierr); 1788 } 1789 PetscFunctionReturn(0); 1790 } 1791 1792 #undef __FUNCT__ 1793 #define __FUNCT__ "TSMonitor" 1794 /* 1795 Runs the user provided monitor routines, if they exists. 1796 */ 1797 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec x) 1798 { 1799 PetscErrorCode ierr; 1800 PetscInt i,n = ts->numbermonitors; 1801 1802 PetscFunctionBegin; 1803 for (i=0; i<n; i++) { 1804 ierr = (*ts->monitor[i])(ts,step,ptime,x,ts->monitorcontext[i]);CHKERRQ(ierr); 1805 } 1806 PetscFunctionReturn(0); 1807 } 1808 1809 /* ------------------------------------------------------------------------*/ 1810 1811 #undef __FUNCT__ 1812 #define __FUNCT__ "TSMonitorLGCreate" 1813 /*@C 1814 TSMonitorLGCreate - Creates a line graph context for use with 1815 TS to monitor convergence of preconditioned residual norms. 1816 1817 Collective on TS 1818 1819 Input Parameters: 1820 + host - the X display to open, or null for the local machine 1821 . label - the title to put in the title bar 1822 . x, y - the screen coordinates of the upper left coordinate of the window 1823 - m, n - the screen width and height in pixels 1824 1825 Output Parameter: 1826 . draw - the drawing context 1827 1828 Options Database Key: 1829 . -ts_monitor_draw - automatically sets line graph monitor 1830 1831 Notes: 1832 Use TSMonitorLGDestroy() to destroy this line graph, not PetscDrawLGDestroy(). 1833 1834 Level: intermediate 1835 1836 .keywords: TS, monitor, line graph, residual, seealso 1837 1838 .seealso: TSMonitorLGDestroy(), TSMonitorSet() 1839 1840 @*/ 1841 PetscErrorCode TSMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 1842 { 1843 PetscDraw win; 1844 PetscErrorCode ierr; 1845 1846 PetscFunctionBegin; 1847 ierr = PetscDrawCreate(PETSC_COMM_SELF,host,label,x,y,m,n,&win);CHKERRQ(ierr); 1848 ierr = PetscDrawSetType(win,PETSC_DRAW_X);CHKERRQ(ierr); 1849 ierr = PetscDrawLGCreate(win,1,draw);CHKERRQ(ierr); 1850 ierr = PetscDrawLGIndicateDataPoints(*draw);CHKERRQ(ierr); 1851 1852 ierr = PetscLogObjectParent(*draw,win);CHKERRQ(ierr); 1853 PetscFunctionReturn(0); 1854 } 1855 1856 #undef __FUNCT__ 1857 #define __FUNCT__ "TSMonitorLG" 1858 PetscErrorCode TSMonitorLG(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 1859 { 1860 PetscDrawLG lg = (PetscDrawLG) monctx; 1861 PetscReal x,y = ptime; 1862 PetscErrorCode ierr; 1863 1864 PetscFunctionBegin; 1865 if (!monctx) { 1866 MPI_Comm comm; 1867 PetscViewer viewer; 1868 1869 ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr); 1870 viewer = PETSC_VIEWER_DRAW_(comm); 1871 ierr = PetscViewerDrawGetDrawLG(viewer,0,&lg);CHKERRQ(ierr); 1872 } 1873 1874 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 1875 x = (PetscReal)n; 1876 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 1877 if (n < 20 || (n % 5)) { 1878 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 1879 } 1880 PetscFunctionReturn(0); 1881 } 1882 1883 #undef __FUNCT__ 1884 #define __FUNCT__ "TSMonitorLGDestroy" 1885 /*@C 1886 TSMonitorLGDestroy - Destroys a line graph context that was created 1887 with TSMonitorLGCreate(). 1888 1889 Collective on PetscDrawLG 1890 1891 Input Parameter: 1892 . draw - the drawing context 1893 1894 Level: intermediate 1895 1896 .keywords: TS, monitor, line graph, destroy 1897 1898 .seealso: TSMonitorLGCreate(), TSMonitorSet(), TSMonitorLG(); 1899 @*/ 1900 PetscErrorCode TSMonitorLGDestroy(PetscDrawLG *drawlg) 1901 { 1902 PetscDraw draw; 1903 PetscErrorCode ierr; 1904 1905 PetscFunctionBegin; 1906 ierr = PetscDrawLGGetDraw(*drawlg,&draw);CHKERRQ(ierr); 1907 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 1908 ierr = PetscDrawLGDestroy(drawlg);CHKERRQ(ierr); 1909 PetscFunctionReturn(0); 1910 } 1911 1912 #undef __FUNCT__ 1913 #define __FUNCT__ "TSGetTime" 1914 /*@ 1915 TSGetTime - Gets the current time. 1916 1917 Not Collective 1918 1919 Input Parameter: 1920 . ts - the TS context obtained from TSCreate() 1921 1922 Output Parameter: 1923 . t - the current time 1924 1925 Level: beginner 1926 1927 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 1928 1929 .keywords: TS, get, time 1930 @*/ 1931 PetscErrorCode TSGetTime(TS ts,PetscReal* t) 1932 { 1933 PetscFunctionBegin; 1934 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1935 PetscValidDoublePointer(t,2); 1936 *t = ts->ptime; 1937 PetscFunctionReturn(0); 1938 } 1939 1940 #undef __FUNCT__ 1941 #define __FUNCT__ "TSSetTime" 1942 /*@ 1943 TSSetTime - Allows one to reset the time. 1944 1945 Logically Collective on TS 1946 1947 Input Parameters: 1948 + ts - the TS context obtained from TSCreate() 1949 - time - the time 1950 1951 Level: intermediate 1952 1953 .seealso: TSGetTime(), TSSetDuration() 1954 1955 .keywords: TS, set, time 1956 @*/ 1957 PetscErrorCode TSSetTime(TS ts, PetscReal t) 1958 { 1959 PetscFunctionBegin; 1960 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1961 PetscValidLogicalCollectiveReal(ts,t,2); 1962 ts->ptime = t; 1963 PetscFunctionReturn(0); 1964 } 1965 1966 #undef __FUNCT__ 1967 #define __FUNCT__ "TSSetOptionsPrefix" 1968 /*@C 1969 TSSetOptionsPrefix - Sets the prefix used for searching for all 1970 TS options in the database. 1971 1972 Logically Collective on TS 1973 1974 Input Parameter: 1975 + ts - The TS context 1976 - prefix - The prefix to prepend to all option names 1977 1978 Notes: 1979 A hyphen (-) must NOT be given at the beginning of the prefix name. 1980 The first character of all runtime options is AUTOMATICALLY the 1981 hyphen. 1982 1983 Level: advanced 1984 1985 .keywords: TS, set, options, prefix, database 1986 1987 .seealso: TSSetFromOptions() 1988 1989 @*/ 1990 PetscErrorCode TSSetOptionsPrefix(TS ts,const char prefix[]) 1991 { 1992 PetscErrorCode ierr; 1993 SNES snes; 1994 1995 PetscFunctionBegin; 1996 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1997 ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 1998 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1999 ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr); 2000 PetscFunctionReturn(0); 2001 } 2002 2003 2004 #undef __FUNCT__ 2005 #define __FUNCT__ "TSAppendOptionsPrefix" 2006 /*@C 2007 TSAppendOptionsPrefix - Appends to the prefix used for searching for all 2008 TS options in the database. 2009 2010 Logically Collective on TS 2011 2012 Input Parameter: 2013 + ts - The TS context 2014 - prefix - The prefix to prepend to all option names 2015 2016 Notes: 2017 A hyphen (-) must NOT be given at the beginning of the prefix name. 2018 The first character of all runtime options is AUTOMATICALLY the 2019 hyphen. 2020 2021 Level: advanced 2022 2023 .keywords: TS, append, options, prefix, database 2024 2025 .seealso: TSGetOptionsPrefix() 2026 2027 @*/ 2028 PetscErrorCode TSAppendOptionsPrefix(TS ts,const char prefix[]) 2029 { 2030 PetscErrorCode ierr; 2031 SNES snes; 2032 2033 PetscFunctionBegin; 2034 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2035 ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 2036 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2037 ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr); 2038 PetscFunctionReturn(0); 2039 } 2040 2041 #undef __FUNCT__ 2042 #define __FUNCT__ "TSGetOptionsPrefix" 2043 /*@C 2044 TSGetOptionsPrefix - Sets the prefix used for searching for all 2045 TS options in the database. 2046 2047 Not Collective 2048 2049 Input Parameter: 2050 . ts - The TS context 2051 2052 Output Parameter: 2053 . prefix - A pointer to the prefix string used 2054 2055 Notes: On the fortran side, the user should pass in a string 'prifix' of 2056 sufficient length to hold the prefix. 2057 2058 Level: intermediate 2059 2060 .keywords: TS, get, options, prefix, database 2061 2062 .seealso: TSAppendOptionsPrefix() 2063 @*/ 2064 PetscErrorCode TSGetOptionsPrefix(TS ts,const char *prefix[]) 2065 { 2066 PetscErrorCode ierr; 2067 2068 PetscFunctionBegin; 2069 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2070 PetscValidPointer(prefix,2); 2071 ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 2072 PetscFunctionReturn(0); 2073 } 2074 2075 #undef __FUNCT__ 2076 #define __FUNCT__ "TSGetRHSJacobian" 2077 /*@C 2078 TSGetRHSJacobian - Returns the Jacobian J at the present timestep. 2079 2080 Not Collective, but parallel objects are returned if TS is parallel 2081 2082 Input Parameter: 2083 . ts - The TS context obtained from TSCreate() 2084 2085 Output Parameters: 2086 + J - The Jacobian J of F, where U_t = F(U,t) 2087 . M - The preconditioner matrix, usually the same as J 2088 . func - Function to compute the Jacobian of the RHS 2089 - ctx - User-defined context for Jacobian evaluation routine 2090 2091 Notes: You can pass in PETSC_NULL for any return argument you do not need. 2092 2093 Level: intermediate 2094 2095 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 2096 2097 .keywords: TS, timestep, get, matrix, Jacobian 2098 @*/ 2099 PetscErrorCode TSGetRHSJacobian(TS ts,Mat *J,Mat *M,TSRHSJacobian *func,void **ctx) 2100 { 2101 PetscErrorCode ierr; 2102 SNES snes; 2103 2104 PetscFunctionBegin; 2105 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2106 ierr = SNESGetJacobian(snes,J,M,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 2107 if (func) *func = ts->userops->rhsjacobian; 2108 if (ctx) *ctx = ts->jacP; 2109 PetscFunctionReturn(0); 2110 } 2111 2112 #undef __FUNCT__ 2113 #define __FUNCT__ "TSGetIJacobian" 2114 /*@C 2115 TSGetIJacobian - Returns the implicit Jacobian at the present timestep. 2116 2117 Not Collective, but parallel objects are returned if TS is parallel 2118 2119 Input Parameter: 2120 . ts - The TS context obtained from TSCreate() 2121 2122 Output Parameters: 2123 + A - The Jacobian of F(t,U,U_t) 2124 . B - The preconditioner matrix, often the same as A 2125 . f - The function to compute the matrices 2126 - ctx - User-defined context for Jacobian evaluation routine 2127 2128 Notes: You can pass in PETSC_NULL for any return argument you do not need. 2129 2130 Level: advanced 2131 2132 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 2133 2134 .keywords: TS, timestep, get, matrix, Jacobian 2135 @*/ 2136 PetscErrorCode TSGetIJacobian(TS ts,Mat *A,Mat *B,TSIJacobian *f,void **ctx) 2137 { 2138 PetscErrorCode ierr; 2139 SNES snes; 2140 2141 PetscFunctionBegin; 2142 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2143 ierr = SNESGetJacobian(snes,A,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 2144 if (f) *f = ts->userops->ijacobian; 2145 if (ctx) *ctx = ts->jacP; 2146 PetscFunctionReturn(0); 2147 } 2148 2149 #undef __FUNCT__ 2150 #define __FUNCT__ "TSMonitorSolution" 2151 /*@C 2152 TSMonitorSolution - Monitors progress of the TS solvers by calling 2153 VecView() for the solution at each timestep 2154 2155 Collective on TS 2156 2157 Input Parameters: 2158 + ts - the TS context 2159 . step - current time-step 2160 . ptime - current time 2161 - dummy - either a viewer or PETSC_NULL 2162 2163 Level: intermediate 2164 2165 .keywords: TS, vector, monitor, view 2166 2167 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 2168 @*/ 2169 PetscErrorCode TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec x,void *dummy) 2170 { 2171 PetscErrorCode ierr; 2172 PetscViewer viewer = (PetscViewer) dummy; 2173 2174 PetscFunctionBegin; 2175 if (!dummy) { 2176 viewer = PETSC_VIEWER_DRAW_(((PetscObject)ts)->comm); 2177 } 2178 ierr = VecView(x,viewer);CHKERRQ(ierr); 2179 PetscFunctionReturn(0); 2180 } 2181 2182 2183 #undef __FUNCT__ 2184 #define __FUNCT__ "TSSetDM" 2185 /*@ 2186 TSSetDM - Sets the DM that may be used by some preconditioners 2187 2188 Logically Collective on TS and DM 2189 2190 Input Parameters: 2191 + ts - the preconditioner context 2192 - dm - the dm 2193 2194 Level: intermediate 2195 2196 2197 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM() 2198 @*/ 2199 PetscErrorCode TSSetDM(TS ts,DM dm) 2200 { 2201 PetscErrorCode ierr; 2202 SNES snes; 2203 2204 PetscFunctionBegin; 2205 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2206 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 2207 ierr = DMDestroy(&ts->dm);CHKERRQ(ierr); 2208 ts->dm = dm; 2209 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2210 ierr = SNESSetDM(snes,dm);CHKERRQ(ierr); 2211 PetscFunctionReturn(0); 2212 } 2213 2214 #undef __FUNCT__ 2215 #define __FUNCT__ "TSGetDM" 2216 /*@ 2217 TSGetDM - Gets the DM that may be used by some preconditioners 2218 2219 Not Collective 2220 2221 Input Parameter: 2222 . ts - the preconditioner context 2223 2224 Output Parameter: 2225 . dm - the dm 2226 2227 Level: intermediate 2228 2229 2230 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM() 2231 @*/ 2232 PetscErrorCode TSGetDM(TS ts,DM *dm) 2233 { 2234 PetscFunctionBegin; 2235 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2236 *dm = ts->dm; 2237 PetscFunctionReturn(0); 2238 } 2239 2240 #undef __FUNCT__ 2241 #define __FUNCT__ "SNESTSFormFunction" 2242 /*@ 2243 SNESTSFormFunction - Function to evaluate nonlinear residual 2244 2245 Logically Collective on SNES 2246 2247 Input Parameter: 2248 + snes - nonlinear solver 2249 . X - the current state at which to evaluate the residual 2250 - ctx - user context, must be a TS 2251 2252 Output Parameter: 2253 . F - the nonlinear residual 2254 2255 Notes: 2256 This function is not normally called by users and is automatically registered with the SNES used by TS. 2257 It is most frequently passed to MatFDColoringSetFunction(). 2258 2259 Level: advanced 2260 2261 .seealso: SNESSetFunction(), MatFDColoringSetFunction() 2262 @*/ 2263 PetscErrorCode SNESTSFormFunction(SNES snes,Vec X,Vec F,void *ctx) 2264 { 2265 TS ts = (TS)ctx; 2266 PetscErrorCode ierr; 2267 2268 PetscFunctionBegin; 2269 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2270 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2271 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 2272 PetscValidHeaderSpecific(ts,TS_CLASSID,4); 2273 ierr = (ts->ops->snesfunction)(snes,X,F,ts);CHKERRQ(ierr); 2274 PetscFunctionReturn(0); 2275 } 2276 2277 #undef __FUNCT__ 2278 #define __FUNCT__ "SNESTSFormJacobian" 2279 /*@ 2280 SNESTSFormJacobian - Function to evaluate the Jacobian 2281 2282 Collective on SNES 2283 2284 Input Parameter: 2285 + snes - nonlinear solver 2286 . X - the current state at which to evaluate the residual 2287 - ctx - user context, must be a TS 2288 2289 Output Parameter: 2290 + A - the Jacobian 2291 . B - the preconditioning matrix (may be the same as A) 2292 - flag - indicates any structure change in the matrix 2293 2294 Notes: 2295 This function is not normally called by users and is automatically registered with the SNES used by TS. 2296 2297 Level: developer 2298 2299 .seealso: SNESSetJacobian() 2300 @*/ 2301 PetscErrorCode SNESTSFormJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flag,void *ctx) 2302 { 2303 TS ts = (TS)ctx; 2304 PetscErrorCode ierr; 2305 2306 PetscFunctionBegin; 2307 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2308 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2309 PetscValidPointer(A,3); 2310 PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 2311 PetscValidPointer(B,4); 2312 PetscValidHeaderSpecific(*B,MAT_CLASSID,4); 2313 PetscValidPointer(flag,5); 2314 PetscValidHeaderSpecific(ts,TS_CLASSID,6); 2315 ierr = (ts->ops->snesjacobian)(snes,X,A,B,flag,ts);CHKERRQ(ierr); 2316 PetscFunctionReturn(0); 2317 } 2318 2319 #undef __FUNCT__ 2320 #define __FUNCT__ "TSComputeRHSFunctionLinear" 2321 /*@C 2322 TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems only 2323 2324 Collective on TS 2325 2326 Input Arguments: 2327 + ts - time stepping context 2328 . t - time at which to evaluate 2329 . X - state at which to evaluate 2330 - ctx - context 2331 2332 Output Arguments: 2333 . F - right hand side 2334 2335 Level: intermediate 2336 2337 Notes: 2338 This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems. 2339 The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian(). 2340 2341 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 2342 @*/ 2343 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec X,Vec F,void *ctx) 2344 { 2345 PetscErrorCode ierr; 2346 Mat Arhs,Brhs; 2347 MatStructure flg2; 2348 2349 PetscFunctionBegin; 2350 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 2351 ierr = TSComputeRHSJacobian(ts,t,X,&Arhs,&Brhs,&flg2);CHKERRQ(ierr); 2352 ierr = MatMult(Arhs,X,F);CHKERRQ(ierr); 2353 PetscFunctionReturn(0); 2354 } 2355 2356 #undef __FUNCT__ 2357 #define __FUNCT__ "TSComputeRHSJacobianConstant" 2358 /*@C 2359 TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent. 2360 2361 Collective on TS 2362 2363 Input Arguments: 2364 + ts - time stepping context 2365 . t - time at which to evaluate 2366 . X - state at which to evaluate 2367 - ctx - context 2368 2369 Output Arguments: 2370 + A - pointer to operator 2371 . B - pointer to preconditioning matrix 2372 - flg - matrix structure flag 2373 2374 Level: intermediate 2375 2376 Notes: 2377 This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems. 2378 2379 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear() 2380 @*/ 2381 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec X,Mat *A,Mat *B,MatStructure *flg,void *ctx) 2382 { 2383 2384 PetscFunctionBegin; 2385 *flg = SAME_PRECONDITIONER; 2386 PetscFunctionReturn(0); 2387 } 2388 2389 #undef __FUNCT__ 2390 #define __FUNCT__ "TSComputeIFunctionLinear" 2391 /*@C 2392 TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only 2393 2394 Collective on TS 2395 2396 Input Arguments: 2397 + ts - time stepping context 2398 . t - time at which to evaluate 2399 . X - state at which to evaluate 2400 . Xdot - time derivative of state vector 2401 - ctx - context 2402 2403 Output Arguments: 2404 . F - left hand side 2405 2406 Level: intermediate 2407 2408 Notes: 2409 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 2410 user is required to write their own TSComputeIFunction. 2411 This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems. 2412 The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian(). 2413 2414 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant() 2415 @*/ 2416 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec X,Vec Xdot,Vec F,void *ctx) 2417 { 2418 PetscErrorCode ierr; 2419 Mat A,B; 2420 MatStructure flg2; 2421 2422 PetscFunctionBegin; 2423 ierr = TSGetIJacobian(ts,&A,&B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 2424 ierr = TSComputeIJacobian(ts,t,X,Xdot,1.0,&A,&B,&flg2,PETSC_TRUE);CHKERRQ(ierr); 2425 ierr = MatMult(A,Xdot,F);CHKERRQ(ierr); 2426 PetscFunctionReturn(0); 2427 } 2428 2429 #undef __FUNCT__ 2430 #define __FUNCT__ "TSComputeIJacobianConstant" 2431 /*@C 2432 TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent. 2433 2434 Collective on TS 2435 2436 Input Arguments: 2437 + ts - time stepping context 2438 . t - time at which to evaluate 2439 . X - state at which to evaluate 2440 . Xdot - time derivative of state vector 2441 . shift - shift to apply 2442 - ctx - context 2443 2444 Output Arguments: 2445 + A - pointer to operator 2446 . B - pointer to preconditioning matrix 2447 - flg - matrix structure flag 2448 2449 Level: intermediate 2450 2451 Notes: 2452 This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems. 2453 2454 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear() 2455 @*/ 2456 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec X,Vec Xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,void *ctx) 2457 { 2458 2459 PetscFunctionBegin; 2460 *flg = SAME_PRECONDITIONER; 2461 PetscFunctionReturn(0); 2462 } 2463 2464 2465 #undef __FUNCT__ 2466 #define __FUNCT__ "TSGetConvergedReason" 2467 /*@ 2468 TSGetConvergedReason - Gets the reason the TS iteration was stopped. 2469 2470 Not Collective 2471 2472 Input Parameter: 2473 . ts - the TS context 2474 2475 Output Parameter: 2476 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 2477 manual pages for the individual convergence tests for complete lists 2478 2479 Level: intermediate 2480 2481 Notes: Can only be called after the call to TSSolve() is complete. 2482 2483 .keywords: TS, nonlinear, set, convergence, test 2484 2485 .seealso: TSSetConvergenceTest(), TSConvergedReason 2486 @*/ 2487 PetscErrorCode TSGetConvergedReason(TS ts,TSConvergedReason *reason) 2488 { 2489 PetscFunctionBegin; 2490 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2491 PetscValidPointer(reason,2); 2492 *reason = ts->reason; 2493 PetscFunctionReturn(0); 2494 } 2495 2496 #if defined(PETSC_HAVE_MATLAB_ENGINE) 2497 #include <mex.h> 2498 2499 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext; 2500 2501 #undef __FUNCT__ 2502 #define __FUNCT__ "TSComputeFunction_Matlab" 2503 /* 2504 TSComputeFunction_Matlab - Calls the function that has been set with 2505 TSSetFunctionMatlab(). 2506 2507 Collective on TS 2508 2509 Input Parameters: 2510 + snes - the TS context 2511 - x - input vector 2512 2513 Output Parameter: 2514 . y - function vector, as set by TSSetFunction() 2515 2516 Notes: 2517 TSComputeFunction() is typically used within nonlinear solvers 2518 implementations, so most users would not generally call this routine 2519 themselves. 2520 2521 Level: developer 2522 2523 .keywords: TS, nonlinear, compute, function 2524 2525 .seealso: TSSetFunction(), TSGetFunction() 2526 */ 2527 PetscErrorCode TSComputeFunction_Matlab(TS snes,PetscReal time,Vec x,Vec xdot,Vec y, void *ctx) 2528 { 2529 PetscErrorCode ierr; 2530 TSMatlabContext *sctx = (TSMatlabContext *)ctx; 2531 int nlhs = 1,nrhs = 7; 2532 mxArray *plhs[1],*prhs[7]; 2533 long long int lx = 0,lxdot = 0,ly = 0,ls = 0; 2534 2535 PetscFunctionBegin; 2536 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 2537 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 2538 PetscValidHeaderSpecific(xdot,VEC_CLASSID,4); 2539 PetscValidHeaderSpecific(y,VEC_CLASSID,5); 2540 PetscCheckSameComm(snes,1,x,3); 2541 PetscCheckSameComm(snes,1,y,5); 2542 2543 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 2544 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 2545 ierr = PetscMemcpy(&lxdot,&xdot,sizeof(xdot));CHKERRQ(ierr); 2546 ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 2547 prhs[0] = mxCreateDoubleScalar((double)ls); 2548 prhs[1] = mxCreateDoubleScalar(time); 2549 prhs[2] = mxCreateDoubleScalar((double)lx); 2550 prhs[3] = mxCreateDoubleScalar((double)lxdot); 2551 prhs[4] = mxCreateDoubleScalar((double)ly); 2552 prhs[5] = mxCreateString(sctx->funcname); 2553 prhs[6] = sctx->ctx; 2554 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr); 2555 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 2556 mxDestroyArray(prhs[0]); 2557 mxDestroyArray(prhs[1]); 2558 mxDestroyArray(prhs[2]); 2559 mxDestroyArray(prhs[3]); 2560 mxDestroyArray(prhs[4]); 2561 mxDestroyArray(prhs[5]); 2562 mxDestroyArray(plhs[0]); 2563 PetscFunctionReturn(0); 2564 } 2565 2566 2567 #undef __FUNCT__ 2568 #define __FUNCT__ "TSSetFunctionMatlab" 2569 /* 2570 TSSetFunctionMatlab - Sets the function evaluation routine and function 2571 vector for use by the TS routines in solving ODEs 2572 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 2573 2574 Logically Collective on TS 2575 2576 Input Parameters: 2577 + ts - the TS context 2578 - func - function evaluation routine 2579 2580 Calling sequence of func: 2581 $ func (TS ts,PetscReal time,Vec x,Vec xdot,Vec f,void *ctx); 2582 2583 Level: beginner 2584 2585 .keywords: TS, nonlinear, set, function 2586 2587 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 2588 */ 2589 PetscErrorCode TSSetFunctionMatlab(TS snes,const char *func,mxArray *ctx) 2590 { 2591 PetscErrorCode ierr; 2592 TSMatlabContext *sctx; 2593 2594 PetscFunctionBegin; 2595 /* currently sctx is memory bleed */ 2596 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 2597 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 2598 /* 2599 This should work, but it doesn't 2600 sctx->ctx = ctx; 2601 mexMakeArrayPersistent(sctx->ctx); 2602 */ 2603 sctx->ctx = mxDuplicateArray(ctx); 2604 ierr = TSSetIFunction(snes,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr); 2605 PetscFunctionReturn(0); 2606 } 2607 2608 #undef __FUNCT__ 2609 #define __FUNCT__ "TSComputeJacobian_Matlab" 2610 /* 2611 TSComputeJacobian_Matlab - Calls the function that has been set with 2612 TSSetJacobianMatlab(). 2613 2614 Collective on TS 2615 2616 Input Parameters: 2617 + snes - the TS context 2618 . x - input vector 2619 . A, B - the matrices 2620 - ctx - user context 2621 2622 Output Parameter: 2623 . flag - structure of the matrix 2624 2625 Level: developer 2626 2627 .keywords: TS, nonlinear, compute, function 2628 2629 .seealso: TSSetFunction(), TSGetFunction() 2630 @*/ 2631 PetscErrorCode TSComputeJacobian_Matlab(TS snes,PetscReal time,Vec x,Vec xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flag, void *ctx) 2632 { 2633 PetscErrorCode ierr; 2634 TSMatlabContext *sctx = (TSMatlabContext *)ctx; 2635 int nlhs = 2,nrhs = 9; 2636 mxArray *plhs[2],*prhs[9]; 2637 long long int lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0; 2638 2639 PetscFunctionBegin; 2640 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 2641 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 2642 2643 /* call Matlab function in ctx with arguments x and y */ 2644 2645 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 2646 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 2647 ierr = PetscMemcpy(&lxdot,&xdot,sizeof(x));CHKERRQ(ierr); 2648 ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 2649 ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 2650 prhs[0] = mxCreateDoubleScalar((double)ls); 2651 prhs[1] = mxCreateDoubleScalar((double)time); 2652 prhs[2] = mxCreateDoubleScalar((double)lx); 2653 prhs[3] = mxCreateDoubleScalar((double)lxdot); 2654 prhs[4] = mxCreateDoubleScalar((double)shift); 2655 prhs[5] = mxCreateDoubleScalar((double)lA); 2656 prhs[6] = mxCreateDoubleScalar((double)lB); 2657 prhs[7] = mxCreateString(sctx->funcname); 2658 prhs[8] = sctx->ctx; 2659 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr); 2660 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 2661 *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 2662 mxDestroyArray(prhs[0]); 2663 mxDestroyArray(prhs[1]); 2664 mxDestroyArray(prhs[2]); 2665 mxDestroyArray(prhs[3]); 2666 mxDestroyArray(prhs[4]); 2667 mxDestroyArray(prhs[5]); 2668 mxDestroyArray(prhs[6]); 2669 mxDestroyArray(prhs[7]); 2670 mxDestroyArray(plhs[0]); 2671 mxDestroyArray(plhs[1]); 2672 PetscFunctionReturn(0); 2673 } 2674 2675 2676 #undef __FUNCT__ 2677 #define __FUNCT__ "TSSetJacobianMatlab" 2678 /* 2679 TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 2680 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 2681 2682 Logically Collective on TS 2683 2684 Input Parameters: 2685 + snes - the TS context 2686 . A,B - Jacobian matrices 2687 . func - function evaluation routine 2688 - ctx - user context 2689 2690 Calling sequence of func: 2691 $ flag = func (TS snes,PetscReal time,Vec x,Vec xdot,Mat A,Mat B,void *ctx); 2692 2693 2694 Level: developer 2695 2696 .keywords: TS, nonlinear, set, function 2697 2698 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 2699 */ 2700 PetscErrorCode TSSetJacobianMatlab(TS snes,Mat A,Mat B,const char *func,mxArray *ctx) 2701 { 2702 PetscErrorCode ierr; 2703 TSMatlabContext *sctx; 2704 2705 PetscFunctionBegin; 2706 /* currently sctx is memory bleed */ 2707 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 2708 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 2709 /* 2710 This should work, but it doesn't 2711 sctx->ctx = ctx; 2712 mexMakeArrayPersistent(sctx->ctx); 2713 */ 2714 sctx->ctx = mxDuplicateArray(ctx); 2715 ierr = TSSetIJacobian(snes,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 2716 PetscFunctionReturn(0); 2717 } 2718 2719 #undef __FUNCT__ 2720 #define __FUNCT__ "TSMonitor_Matlab" 2721 /* 2722 TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab(). 2723 2724 Collective on TS 2725 2726 .seealso: TSSetFunction(), TSGetFunction() 2727 @*/ 2728 PetscErrorCode TSMonitor_Matlab(TS snes,PetscInt it, PetscReal time,Vec x, void *ctx) 2729 { 2730 PetscErrorCode ierr; 2731 TSMatlabContext *sctx = (TSMatlabContext *)ctx; 2732 int nlhs = 1,nrhs = 6; 2733 mxArray *plhs[1],*prhs[6]; 2734 long long int lx = 0,ls = 0; 2735 2736 PetscFunctionBegin; 2737 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 2738 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 2739 2740 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 2741 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 2742 prhs[0] = mxCreateDoubleScalar((double)ls); 2743 prhs[1] = mxCreateDoubleScalar((double)it); 2744 prhs[2] = mxCreateDoubleScalar((double)time); 2745 prhs[3] = mxCreateDoubleScalar((double)lx); 2746 prhs[4] = mxCreateString(sctx->funcname); 2747 prhs[5] = sctx->ctx; 2748 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr); 2749 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 2750 mxDestroyArray(prhs[0]); 2751 mxDestroyArray(prhs[1]); 2752 mxDestroyArray(prhs[2]); 2753 mxDestroyArray(prhs[3]); 2754 mxDestroyArray(prhs[4]); 2755 mxDestroyArray(plhs[0]); 2756 PetscFunctionReturn(0); 2757 } 2758 2759 2760 #undef __FUNCT__ 2761 #define __FUNCT__ "TSMonitorSetMatlab" 2762 /* 2763 TSMonitorSetMatlab - Sets the monitor function from Matlab 2764 2765 Level: developer 2766 2767 .keywords: TS, nonlinear, set, function 2768 2769 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 2770 */ 2771 PetscErrorCode TSMonitorSetMatlab(TS snes,const char *func,mxArray *ctx) 2772 { 2773 PetscErrorCode ierr; 2774 TSMatlabContext *sctx; 2775 2776 PetscFunctionBegin; 2777 /* currently sctx is memory bleed */ 2778 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 2779 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 2780 /* 2781 This should work, but it doesn't 2782 sctx->ctx = ctx; 2783 mexMakeArrayPersistent(sctx->ctx); 2784 */ 2785 sctx->ctx = mxDuplicateArray(ctx); 2786 ierr = TSMonitorSet(snes,TSMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 2787 PetscFunctionReturn(0); 2788 } 2789 2790 #endif 2791