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