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