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 PetscViewerASCIIMonitor 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 = PetscViewerASCIIMonitorCreate(((PetscObject)ts)->comm,monfilename,((PetscObject)ts)->tablevel,&monviewer);CHKERRQ(ierr); 96 ierr = TSMonitorSet(ts,TSMonitorDefault,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);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 PetscFunctionBegin; 578 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 579 if (Arhs){ 580 PetscValidHeaderSpecific(Arhs,MAT_CLASSID,2); 581 PetscCheckSameComm(ts,1,Arhs,2); 582 ts->Arhs = Arhs; 583 ts->ops->rhsmatrix = frhs; 584 } 585 if (Alhs){ 586 PetscValidHeaderSpecific(Alhs,MAT_CLASSID,4); 587 PetscCheckSameComm(ts,1,Alhs,4); 588 ts->Alhs = Alhs; 589 ts->ops->lhsmatrix = flhs; 590 } 591 592 ts->jacP = ctx; 593 ts->matflg = flag; 594 PetscFunctionReturn(0); 595 } 596 597 #undef __FUNCT__ 598 #define __FUNCT__ "TSGetMatrices" 599 /*@C 600 TSGetMatrices - Returns the matrices Arhs and Alhs at the present timestep, 601 where Alhs(t) U_t = Arhs(t) U. 602 603 Not Collective, but parallel objects are returned if TS is parallel 604 605 Input Parameter: 606 . ts - The TS context obtained from TSCreate() 607 608 Output Parameters: 609 + Arhs - The right-hand side matrix 610 . Alhs - The left-hand side matrix 611 - ctx - User-defined context for matrix evaluation routine 612 613 Notes: You can pass in PETSC_NULL for any return argument you do not need. 614 615 Level: intermediate 616 617 .seealso: TSSetMatrices(), TSGetTimeStep(), TSGetTime(), TSGetTimeStepNumber(), TSGetRHSJacobian() 618 619 .keywords: TS, timestep, get, matrix 620 621 @*/ 622 PetscErrorCode TSGetMatrices(TS ts,Mat *Arhs,Mat *Alhs,void **ctx) 623 { 624 PetscFunctionBegin; 625 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 626 if (Arhs) *Arhs = ts->Arhs; 627 if (Alhs) *Alhs = ts->Alhs; 628 if (ctx) *ctx = ts->jacP; 629 PetscFunctionReturn(0); 630 } 631 632 #undef __FUNCT__ 633 #define __FUNCT__ "TSSetRHSJacobian" 634 /*@C 635 TSSetRHSJacobian - Sets the function to compute the Jacobian of F, 636 where U_t = F(U,t), as well as the location to store the matrix. 637 Use TSSetMatrices() for linear problems. 638 639 Logically Collective on TS 640 641 Input Parameters: 642 + ts - the TS context obtained from TSCreate() 643 . A - Jacobian matrix 644 . B - preconditioner matrix (usually same as A) 645 . f - the Jacobian evaluation routine 646 - ctx - [optional] user-defined context for private data for the 647 Jacobian evaluation routine (may be PETSC_NULL) 648 649 Calling sequence of func: 650 $ func (TS ts,PetscReal t,Vec u,Mat *A,Mat *B,MatStructure *flag,void *ctx); 651 652 + t - current timestep 653 . u - input vector 654 . A - matrix A, where U_t = A(t)u 655 . B - preconditioner matrix, usually the same as A 656 . flag - flag indicating information about the preconditioner matrix 657 structure (same as flag in KSPSetOperators()) 658 - ctx - [optional] user-defined context for matrix evaluation routine 659 660 Notes: 661 See KSPSetOperators() for important information about setting the flag 662 output parameter in the routine func(). Be sure to read this information! 663 664 The routine func() takes Mat * as the matrix arguments rather than Mat. 665 This allows the matrix evaluation routine to replace A and/or B with a 666 completely new matrix structure (not just different matrix elements) 667 when appropriate, for instance, if the nonzero structure is changing 668 throughout the global iterations. 669 670 Level: beginner 671 672 .keywords: TS, timestep, set, right-hand-side, Jacobian 673 674 .seealso: TSDefaultComputeJacobianColor(), 675 SNESDefaultComputeJacobianColor(), TSSetRHSFunction(), TSSetMatrices() 676 677 @*/ 678 PetscErrorCode TSSetRHSJacobian(TS ts,Mat A,Mat B,PetscErrorCode (*f)(TS,PetscReal,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 679 { 680 PetscFunctionBegin; 681 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 682 PetscValidHeaderSpecific(A,MAT_CLASSID,2); 683 PetscValidHeaderSpecific(B,MAT_CLASSID,3); 684 PetscCheckSameComm(ts,1,A,2); 685 PetscCheckSameComm(ts,1,B,3); 686 if (ts->problem_type != TS_NONLINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not for linear problems; use TSSetMatrices()"); 687 688 ts->ops->rhsjacobian = f; 689 ts->jacP = ctx; 690 ts->Arhs = A; 691 ts->B = B; 692 PetscFunctionReturn(0); 693 } 694 695 696 #undef __FUNCT__ 697 #define __FUNCT__ "TSSetIFunction" 698 /*@C 699 TSSetIFunction - Set the function to compute F(t,U,U_t) where F = 0 is the DAE to be solved. 700 701 Logically Collective on TS 702 703 Input Parameters: 704 + ts - the TS context obtained from TSCreate() 705 . f - the function evaluation routine 706 - ctx - user-defined context for private data for the function evaluation routine (may be PETSC_NULL) 707 708 Calling sequence of f: 709 $ f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx); 710 711 + t - time at step/stage being solved 712 . u - state vector 713 . u_t - time derivative of state vector 714 . F - function vector 715 - ctx - [optional] user-defined context for matrix evaluation routine 716 717 Important: 718 The user MUST call either this routine, TSSetRHSFunction(), or TSSetMatrices(). This routine must be used when not solving an ODE. 719 720 Level: beginner 721 722 .keywords: TS, timestep, set, DAE, Jacobian 723 724 .seealso: TSSetMatrices(), TSSetRHSFunction(), TSSetIJacobian() 725 @*/ 726 PetscErrorCode TSSetIFunction(TS ts,TSIFunction f,void *ctx) 727 { 728 729 PetscFunctionBegin; 730 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 731 ts->ops->ifunction = f; 732 ts->funP = ctx; 733 PetscFunctionReturn(0); 734 } 735 736 #undef __FUNCT__ 737 #define __FUNCT__ "TSSetIJacobian" 738 /*@C 739 TSSetIJacobian - Set the function to compute the matrix dF/dU + a*dF/dU_t which is 740 the Jacobian of G(U) = F(t,U,W+a*U) where F(t,U,U_t) = 0 is the DAE to be solved. 741 The time integrator internally approximates U_t by W+a*U where the positive "shift" 742 a and vector W depend on the integration method, step size, and past states. 743 744 Logically Collective on TS 745 746 Input Parameters: 747 + ts - the TS context obtained from TSCreate() 748 . A - Jacobian matrix 749 . B - preconditioning matrix for A (may be same as A) 750 . f - the Jacobian evaluation routine 751 - ctx - user-defined context for private data for the Jacobian evaluation routine (may be PETSC_NULL) 752 753 Calling sequence of f: 754 $ f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat *A,Mat *B,MatStructure *flag,void *ctx); 755 756 + t - time at step/stage being solved 757 . U - state vector 758 . U_t - time derivative of state vector 759 . a - shift 760 . A - Jacobian of G(U) = F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t 761 . B - preconditioning matrix for A, may be same as A 762 . flag - flag indicating information about the preconditioner matrix 763 structure (same as flag in KSPSetOperators()) 764 - ctx - [optional] user-defined context for matrix evaluation routine 765 766 Notes: 767 The matrices A and B are exactly the matrices that are used by SNES for the nonlinear solve. 768 769 Level: beginner 770 771 .keywords: TS, timestep, DAE, Jacobian 772 773 .seealso: TSSetIFunction(), TSSetRHSJacobian() 774 775 @*/ 776 PetscErrorCode TSSetIJacobian(TS ts,Mat A,Mat B,TSIJacobian f,void *ctx) 777 { 778 PetscErrorCode ierr; 779 780 PetscFunctionBegin; 781 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 782 if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 783 if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 784 if (A) PetscCheckSameComm(ts,1,A,2); 785 if (B) PetscCheckSameComm(ts,1,B,3); 786 if (f) ts->ops->ijacobian = f; 787 if (ctx) ts->jacP = ctx; 788 if (A) { 789 ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 790 if (ts->A) {ierr = MatDestroy(ts->A);CHKERRQ(ierr);} 791 ts->A = A; 792 } 793 #if 0 794 /* The sane and consistent alternative */ 795 if (B) { 796 ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 797 if (ts->B) {ierr = MatDestroy(ts->B);CHKERRQ(ierr);} 798 ts->B = B; 799 } 800 #else 801 /* Don't reference B because TSDestroy() doesn't destroy it. These ownership semantics are awkward and inconsistent. */ 802 if (B) ts->B = B; 803 #endif 804 PetscFunctionReturn(0); 805 } 806 807 #undef __FUNCT__ 808 #define __FUNCT__ "TSView" 809 /*@C 810 TSView - Prints the TS data structure. 811 812 Collective on TS 813 814 Input Parameters: 815 + ts - the TS context obtained from TSCreate() 816 - viewer - visualization context 817 818 Options Database Key: 819 . -ts_view - calls TSView() at end of TSStep() 820 821 Notes: 822 The available visualization contexts include 823 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 824 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 825 output where only the first processor opens 826 the file. All other processors send their 827 data to the first processor to print. 828 829 The user can open an alternative visualization context with 830 PetscViewerASCIIOpen() - output to a specified file. 831 832 Level: beginner 833 834 .keywords: TS, timestep, view 835 836 .seealso: PetscViewerASCIIOpen() 837 @*/ 838 PetscErrorCode TSView(TS ts,PetscViewer viewer) 839 { 840 PetscErrorCode ierr; 841 const TSType type; 842 PetscBool iascii,isstring; 843 844 PetscFunctionBegin; 845 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 846 if (!viewer) { 847 ierr = PetscViewerASCIIGetStdout(((PetscObject)ts)->comm,&viewer);CHKERRQ(ierr); 848 } 849 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 850 PetscCheckSameComm(ts,1,viewer,2); 851 852 ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 853 ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 854 if (iascii) { 855 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ts,viewer,"TS Object");CHKERRQ(ierr); 856 if (ts->ops->view) { 857 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 858 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 859 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 860 } 861 ierr = PetscViewerASCIIPrintf(viewer," maximum steps=%D\n",ts->max_steps);CHKERRQ(ierr); 862 ierr = PetscViewerASCIIPrintf(viewer," maximum time=%G\n",ts->max_time);CHKERRQ(ierr); 863 if (ts->problem_type == TS_NONLINEAR) { 864 ierr = PetscViewerASCIIPrintf(viewer," total number of nonlinear solver iterations=%D\n",ts->nonlinear_its);CHKERRQ(ierr); 865 } 866 ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",ts->linear_its);CHKERRQ(ierr); 867 } else if (isstring) { 868 ierr = TSGetType(ts,&type);CHKERRQ(ierr); 869 ierr = PetscViewerStringSPrintf(viewer," %-7.7s",type);CHKERRQ(ierr); 870 } 871 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 872 if (ts->ksp) {ierr = KSPView(ts->ksp,viewer);CHKERRQ(ierr);} 873 if (ts->snes) {ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr);} 874 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 875 PetscFunctionReturn(0); 876 } 877 878 879 #undef __FUNCT__ 880 #define __FUNCT__ "TSSetApplicationContext" 881 /*@C 882 TSSetApplicationContext - Sets an optional user-defined context for 883 the timesteppers. 884 885 Logically Collective on TS 886 887 Input Parameters: 888 + ts - the TS context obtained from TSCreate() 889 - usrP - optional user context 890 891 Level: intermediate 892 893 .keywords: TS, timestep, set, application, context 894 895 .seealso: TSGetApplicationContext() 896 @*/ 897 PetscErrorCode TSSetApplicationContext(TS ts,void *usrP) 898 { 899 PetscFunctionBegin; 900 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 901 ts->user = usrP; 902 PetscFunctionReturn(0); 903 } 904 905 #undef __FUNCT__ 906 #define __FUNCT__ "TSGetApplicationContext" 907 /*@C 908 TSGetApplicationContext - Gets the user-defined context for the 909 timestepper. 910 911 Not Collective 912 913 Input Parameter: 914 . ts - the TS context obtained from TSCreate() 915 916 Output Parameter: 917 . usrP - user context 918 919 Level: intermediate 920 921 .keywords: TS, timestep, get, application, context 922 923 .seealso: TSSetApplicationContext() 924 @*/ 925 PetscErrorCode TSGetApplicationContext(TS ts,void **usrP) 926 { 927 PetscFunctionBegin; 928 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 929 *usrP = ts->user; 930 PetscFunctionReturn(0); 931 } 932 933 #undef __FUNCT__ 934 #define __FUNCT__ "TSGetTimeStepNumber" 935 /*@ 936 TSGetTimeStepNumber - Gets the current number of timesteps. 937 938 Not Collective 939 940 Input Parameter: 941 . ts - the TS context obtained from TSCreate() 942 943 Output Parameter: 944 . iter - number steps so far 945 946 Level: intermediate 947 948 .keywords: TS, timestep, get, iteration, number 949 @*/ 950 PetscErrorCode TSGetTimeStepNumber(TS ts,PetscInt* iter) 951 { 952 PetscFunctionBegin; 953 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 954 PetscValidIntPointer(iter,2); 955 *iter = ts->steps; 956 PetscFunctionReturn(0); 957 } 958 959 #undef __FUNCT__ 960 #define __FUNCT__ "TSSetInitialTimeStep" 961 /*@ 962 TSSetInitialTimeStep - Sets the initial timestep to be used, 963 as well as the initial time. 964 965 Logically Collective on TS 966 967 Input Parameters: 968 + ts - the TS context obtained from TSCreate() 969 . initial_time - the initial time 970 - time_step - the size of the timestep 971 972 Level: intermediate 973 974 .seealso: TSSetTimeStep(), TSGetTimeStep() 975 976 .keywords: TS, set, initial, timestep 977 @*/ 978 PetscErrorCode TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step) 979 { 980 PetscFunctionBegin; 981 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 982 ts->time_step = time_step; 983 ts->initial_time_step = time_step; 984 ts->ptime = initial_time; 985 PetscFunctionReturn(0); 986 } 987 988 #undef __FUNCT__ 989 #define __FUNCT__ "TSSetTimeStep" 990 /*@ 991 TSSetTimeStep - Allows one to reset the timestep at any time, 992 useful for simple pseudo-timestepping codes. 993 994 Logically Collective on TS 995 996 Input Parameters: 997 + ts - the TS context obtained from TSCreate() 998 - time_step - the size of the timestep 999 1000 Level: intermediate 1001 1002 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 1003 1004 .keywords: TS, set, timestep 1005 @*/ 1006 PetscErrorCode TSSetTimeStep(TS ts,PetscReal time_step) 1007 { 1008 PetscFunctionBegin; 1009 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1010 PetscValidLogicalCollectiveReal(ts,time_step,2); 1011 ts->time_step = time_step; 1012 PetscFunctionReturn(0); 1013 } 1014 1015 #undef __FUNCT__ 1016 #define __FUNCT__ "TSGetTimeStep" 1017 /*@ 1018 TSGetTimeStep - Gets the current timestep size. 1019 1020 Not Collective 1021 1022 Input Parameter: 1023 . ts - the TS context obtained from TSCreate() 1024 1025 Output Parameter: 1026 . dt - the current timestep size 1027 1028 Level: intermediate 1029 1030 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 1031 1032 .keywords: TS, get, timestep 1033 @*/ 1034 PetscErrorCode TSGetTimeStep(TS ts,PetscReal* dt) 1035 { 1036 PetscFunctionBegin; 1037 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1038 PetscValidDoublePointer(dt,2); 1039 *dt = ts->time_step; 1040 PetscFunctionReturn(0); 1041 } 1042 1043 #undef __FUNCT__ 1044 #define __FUNCT__ "TSGetSolution" 1045 /*@ 1046 TSGetSolution - Returns the solution at the present timestep. It 1047 is valid to call this routine inside the function that you are evaluating 1048 in order to move to the new timestep. This vector not changed until 1049 the solution at the next timestep has been calculated. 1050 1051 Not Collective, but Vec returned is parallel if TS is parallel 1052 1053 Input Parameter: 1054 . ts - the TS context obtained from TSCreate() 1055 1056 Output Parameter: 1057 . v - the vector containing the solution 1058 1059 Level: intermediate 1060 1061 .seealso: TSGetTimeStep() 1062 1063 .keywords: TS, timestep, get, solution 1064 @*/ 1065 PetscErrorCode TSGetSolution(TS ts,Vec *v) 1066 { 1067 PetscFunctionBegin; 1068 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1069 PetscValidPointer(v,2); 1070 *v = ts->vec_sol; 1071 PetscFunctionReturn(0); 1072 } 1073 1074 /* ----- Routines to initialize and destroy a timestepper ---- */ 1075 #undef __FUNCT__ 1076 #define __FUNCT__ "TSSetProblemType" 1077 /*@ 1078 TSSetProblemType - Sets the type of problem to be solved. 1079 1080 Not collective 1081 1082 Input Parameters: 1083 + ts - The TS 1084 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 1085 .vb 1086 U_t = A U 1087 U_t = A(t) U 1088 U_t = F(t,U) 1089 .ve 1090 1091 Level: beginner 1092 1093 .keywords: TS, problem type 1094 .seealso: TSSetUp(), TSProblemType, TS 1095 @*/ 1096 PetscErrorCode TSSetProblemType(TS ts, TSProblemType type) 1097 { 1098 PetscFunctionBegin; 1099 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1100 ts->problem_type = type; 1101 PetscFunctionReturn(0); 1102 } 1103 1104 #undef __FUNCT__ 1105 #define __FUNCT__ "TSGetProblemType" 1106 /*@C 1107 TSGetProblemType - Gets the type of problem to be solved. 1108 1109 Not collective 1110 1111 Input Parameter: 1112 . ts - The TS 1113 1114 Output Parameter: 1115 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 1116 .vb 1117 U_t = A U 1118 U_t = A(t) U 1119 U_t = F(t,U) 1120 .ve 1121 1122 Level: beginner 1123 1124 .keywords: TS, problem type 1125 .seealso: TSSetUp(), TSProblemType, TS 1126 @*/ 1127 PetscErrorCode TSGetProblemType(TS ts, TSProblemType *type) 1128 { 1129 PetscFunctionBegin; 1130 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1131 PetscValidIntPointer(type,2); 1132 *type = ts->problem_type; 1133 PetscFunctionReturn(0); 1134 } 1135 1136 #undef __FUNCT__ 1137 #define __FUNCT__ "TSSetUp" 1138 /*@ 1139 TSSetUp - Sets up the internal data structures for the later use 1140 of a timestepper. 1141 1142 Collective on TS 1143 1144 Input Parameter: 1145 . ts - the TS context obtained from TSCreate() 1146 1147 Notes: 1148 For basic use of the TS solvers the user need not explicitly call 1149 TSSetUp(), since these actions will automatically occur during 1150 the call to TSStep(). However, if one wishes to control this 1151 phase separately, TSSetUp() should be called after TSCreate() 1152 and optional routines of the form TSSetXXX(), but before TSStep(). 1153 1154 Level: advanced 1155 1156 .keywords: TS, timestep, setup 1157 1158 .seealso: TSCreate(), TSStep(), TSDestroy() 1159 @*/ 1160 PetscErrorCode TSSetUp(TS ts) 1161 { 1162 PetscErrorCode ierr; 1163 1164 PetscFunctionBegin; 1165 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1166 if (!ts->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first"); 1167 if (!((PetscObject)ts)->type_name) { 1168 ierr = TSSetType(ts,TSEULER);CHKERRQ(ierr); 1169 } 1170 ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr); 1171 ts->setupcalled = 1; 1172 PetscFunctionReturn(0); 1173 } 1174 1175 #undef __FUNCT__ 1176 #define __FUNCT__ "TSDestroy" 1177 /*@ 1178 TSDestroy - Destroys the timestepper context that was created 1179 with TSCreate(). 1180 1181 Collective on TS 1182 1183 Input Parameter: 1184 . ts - the TS context obtained from TSCreate() 1185 1186 Level: beginner 1187 1188 .keywords: TS, timestepper, destroy 1189 1190 .seealso: TSCreate(), TSSetUp(), TSSolve() 1191 @*/ 1192 PetscErrorCode TSDestroy(TS ts) 1193 { 1194 PetscErrorCode ierr; 1195 1196 PetscFunctionBegin; 1197 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1198 if (--((PetscObject)ts)->refct > 0) PetscFunctionReturn(0); 1199 1200 /* if memory was published with AMS then destroy it */ 1201 ierr = PetscObjectDepublish(ts);CHKERRQ(ierr); 1202 if (ts->vec_sol) {ierr = VecDestroy(ts->vec_sol);CHKERRQ(ierr);} 1203 if (ts->dm) {ierr = DMDestroy(ts->dm);CHKERRQ(ierr);} 1204 if (ts->A) {ierr = MatDestroy(ts->A);CHKERRQ(ierr);} 1205 if (ts->ksp) {ierr = KSPDestroy(ts->ksp);CHKERRQ(ierr);} 1206 if (ts->snes) {ierr = SNESDestroy(ts->snes);CHKERRQ(ierr);} 1207 if (ts->ops->destroy) {ierr = (*(ts)->ops->destroy)(ts);CHKERRQ(ierr);} 1208 ierr = TSMonitorCancel(ts);CHKERRQ(ierr); 1209 ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr); 1210 PetscFunctionReturn(0); 1211 } 1212 1213 #undef __FUNCT__ 1214 #define __FUNCT__ "TSGetSNES" 1215 /*@ 1216 TSGetSNES - Returns the SNES (nonlinear solver) associated with 1217 a TS (timestepper) context. Valid only for nonlinear problems. 1218 1219 Not Collective, but SNES is parallel if TS is parallel 1220 1221 Input Parameter: 1222 . ts - the TS context obtained from TSCreate() 1223 1224 Output Parameter: 1225 . snes - the nonlinear solver context 1226 1227 Notes: 1228 The user can then directly manipulate the SNES context to set various 1229 options, etc. Likewise, the user can then extract and manipulate the 1230 KSP, KSP, and PC contexts as well. 1231 1232 TSGetSNES() does not work for integrators that do not use SNES; in 1233 this case TSGetSNES() returns PETSC_NULL in snes. 1234 1235 Level: beginner 1236 1237 .keywords: timestep, get, SNES 1238 @*/ 1239 PetscErrorCode TSGetSNES(TS ts,SNES *snes) 1240 { 1241 PetscFunctionBegin; 1242 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1243 PetscValidPointer(snes,2); 1244 if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"SNES is not created yet. Call TSSetType() first"); 1245 if (ts->problem_type == TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Nonlinear only; use TSGetKSP()"); 1246 *snes = ts->snes; 1247 PetscFunctionReturn(0); 1248 } 1249 1250 #undef __FUNCT__ 1251 #define __FUNCT__ "TSGetKSP" 1252 /*@ 1253 TSGetKSP - Returns the KSP (linear solver) associated with 1254 a TS (timestepper) context. 1255 1256 Not Collective, but KSP is parallel if TS is parallel 1257 1258 Input Parameter: 1259 . ts - the TS context obtained from TSCreate() 1260 1261 Output Parameter: 1262 . ksp - the nonlinear solver context 1263 1264 Notes: 1265 The user can then directly manipulate the KSP context to set various 1266 options, etc. Likewise, the user can then extract and manipulate the 1267 KSP and PC contexts as well. 1268 1269 TSGetKSP() does not work for integrators that do not use KSP; 1270 in this case TSGetKSP() returns PETSC_NULL in ksp. 1271 1272 Level: beginner 1273 1274 .keywords: timestep, get, KSP 1275 @*/ 1276 PetscErrorCode TSGetKSP(TS ts,KSP *ksp) 1277 { 1278 PetscFunctionBegin; 1279 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1280 PetscValidPointer(ksp,2); 1281 if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first"); 1282 if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()"); 1283 *ksp = ts->ksp; 1284 PetscFunctionReturn(0); 1285 } 1286 1287 /* ----------- Routines to set solver parameters ---------- */ 1288 1289 #undef __FUNCT__ 1290 #define __FUNCT__ "TSGetDuration" 1291 /*@ 1292 TSGetDuration - Gets the maximum number of timesteps to use and 1293 maximum time for iteration. 1294 1295 Not Collective 1296 1297 Input Parameters: 1298 + ts - the TS context obtained from TSCreate() 1299 . maxsteps - maximum number of iterations to use, or PETSC_NULL 1300 - maxtime - final time to iterate to, or PETSC_NULL 1301 1302 Level: intermediate 1303 1304 .keywords: TS, timestep, get, maximum, iterations, time 1305 @*/ 1306 PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime) 1307 { 1308 PetscFunctionBegin; 1309 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1310 if (maxsteps) { 1311 PetscValidIntPointer(maxsteps,2); 1312 *maxsteps = ts->max_steps; 1313 } 1314 if (maxtime ) { 1315 PetscValidScalarPointer(maxtime,3); 1316 *maxtime = ts->max_time; 1317 } 1318 PetscFunctionReturn(0); 1319 } 1320 1321 #undef __FUNCT__ 1322 #define __FUNCT__ "TSSetDuration" 1323 /*@ 1324 TSSetDuration - Sets the maximum number of timesteps to use and 1325 maximum time for iteration. 1326 1327 Logically Collective on TS 1328 1329 Input Parameters: 1330 + ts - the TS context obtained from TSCreate() 1331 . maxsteps - maximum number of iterations to use 1332 - maxtime - final time to iterate to 1333 1334 Options Database Keys: 1335 . -ts_max_steps <maxsteps> - Sets maxsteps 1336 . -ts_max_time <maxtime> - Sets maxtime 1337 1338 Notes: 1339 The default maximum number of iterations is 5000. Default time is 5.0 1340 1341 Level: intermediate 1342 1343 .keywords: TS, timestep, set, maximum, iterations 1344 @*/ 1345 PetscErrorCode TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime) 1346 { 1347 PetscFunctionBegin; 1348 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1349 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 1350 PetscValidLogicalCollectiveReal(ts,maxtime,2); 1351 ts->max_steps = maxsteps; 1352 ts->max_time = maxtime; 1353 PetscFunctionReturn(0); 1354 } 1355 1356 #undef __FUNCT__ 1357 #define __FUNCT__ "TSSetSolution" 1358 /*@ 1359 TSSetSolution - Sets the initial solution vector 1360 for use by the TS routines. 1361 1362 Logically Collective on TS and Vec 1363 1364 Input Parameters: 1365 + ts - the TS context obtained from TSCreate() 1366 - x - the solution vector 1367 1368 Level: beginner 1369 1370 .keywords: TS, timestep, set, solution, initial conditions 1371 @*/ 1372 PetscErrorCode TSSetSolution(TS ts,Vec x) 1373 { 1374 PetscErrorCode ierr; 1375 1376 PetscFunctionBegin; 1377 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1378 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1379 ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 1380 if (ts->vec_sol) {ierr = VecDestroy(ts->vec_sol);CHKERRQ(ierr);} 1381 ts->vec_sol = x; 1382 PetscFunctionReturn(0); 1383 } 1384 1385 #undef __FUNCT__ 1386 #define __FUNCT__ "TSSetPreStep" 1387 /*@C 1388 TSSetPreStep - Sets the general-purpose function 1389 called once at the beginning of each time step. 1390 1391 Logically Collective on TS 1392 1393 Input Parameters: 1394 + ts - The TS context obtained from TSCreate() 1395 - func - The function 1396 1397 Calling sequence of func: 1398 . func (TS ts); 1399 1400 Level: intermediate 1401 1402 .keywords: TS, timestep 1403 @*/ 1404 PetscErrorCode TSSetPreStep(TS ts, PetscErrorCode (*func)(TS)) 1405 { 1406 PetscFunctionBegin; 1407 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1408 ts->ops->prestep = func; 1409 PetscFunctionReturn(0); 1410 } 1411 1412 #undef __FUNCT__ 1413 #define __FUNCT__ "TSPreStep" 1414 /*@C 1415 TSPreStep - Runs the user-defined pre-step function. 1416 1417 Collective on TS 1418 1419 Input Parameters: 1420 . ts - The TS context obtained from TSCreate() 1421 1422 Notes: 1423 TSPreStep() is typically used within time stepping implementations, 1424 so most users would not generally call this routine themselves. 1425 1426 Level: developer 1427 1428 .keywords: TS, timestep 1429 @*/ 1430 PetscErrorCode TSPreStep(TS ts) 1431 { 1432 PetscErrorCode ierr; 1433 1434 PetscFunctionBegin; 1435 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1436 if (ts->ops->prestep) { 1437 PetscStackPush("TS PreStep function"); 1438 ierr = (*ts->ops->prestep)(ts);CHKERRQ(ierr); 1439 PetscStackPop; 1440 } 1441 PetscFunctionReturn(0); 1442 } 1443 1444 #undef __FUNCT__ 1445 #define __FUNCT__ "TSDefaultPreStep" 1446 /*@ 1447 TSDefaultPreStep - The default pre-stepping function which does nothing. 1448 1449 Collective on TS 1450 1451 Input Parameters: 1452 . ts - The TS context obtained from TSCreate() 1453 1454 Level: developer 1455 1456 .keywords: TS, timestep 1457 @*/ 1458 PetscErrorCode TSDefaultPreStep(TS ts) 1459 { 1460 PetscFunctionBegin; 1461 PetscFunctionReturn(0); 1462 } 1463 1464 #undef __FUNCT__ 1465 #define __FUNCT__ "TSSetPostStep" 1466 /*@C 1467 TSSetPostStep - Sets the general-purpose function 1468 called once at the end of each time step. 1469 1470 Logically Collective on TS 1471 1472 Input Parameters: 1473 + ts - The TS context obtained from TSCreate() 1474 - func - The function 1475 1476 Calling sequence of func: 1477 . func (TS ts); 1478 1479 Level: intermediate 1480 1481 .keywords: TS, timestep 1482 @*/ 1483 PetscErrorCode TSSetPostStep(TS ts, PetscErrorCode (*func)(TS)) 1484 { 1485 PetscFunctionBegin; 1486 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1487 ts->ops->poststep = func; 1488 PetscFunctionReturn(0); 1489 } 1490 1491 #undef __FUNCT__ 1492 #define __FUNCT__ "TSPostStep" 1493 /*@C 1494 TSPostStep - Runs the user-defined post-step function. 1495 1496 Collective on TS 1497 1498 Input Parameters: 1499 . ts - The TS context obtained from TSCreate() 1500 1501 Notes: 1502 TSPostStep() is typically used within time stepping implementations, 1503 so most users would not generally call this routine themselves. 1504 1505 Level: developer 1506 1507 .keywords: TS, timestep 1508 @*/ 1509 PetscErrorCode TSPostStep(TS ts) 1510 { 1511 PetscErrorCode ierr; 1512 1513 PetscFunctionBegin; 1514 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1515 if (ts->ops->poststep) { 1516 PetscStackPush("TS PostStep function"); 1517 ierr = (*ts->ops->poststep)(ts);CHKERRQ(ierr); 1518 PetscStackPop; 1519 } 1520 PetscFunctionReturn(0); 1521 } 1522 1523 #undef __FUNCT__ 1524 #define __FUNCT__ "TSDefaultPostStep" 1525 /*@ 1526 TSDefaultPostStep - The default post-stepping function which does nothing. 1527 1528 Collective on TS 1529 1530 Input Parameters: 1531 . ts - The TS context obtained from TSCreate() 1532 1533 Level: developer 1534 1535 .keywords: TS, timestep 1536 @*/ 1537 PetscErrorCode TSDefaultPostStep(TS ts) 1538 { 1539 PetscFunctionBegin; 1540 PetscFunctionReturn(0); 1541 } 1542 1543 /* ------------ Routines to set performance monitoring options ----------- */ 1544 1545 #undef __FUNCT__ 1546 #define __FUNCT__ "TSMonitorSet" 1547 /*@C 1548 TSMonitorSet - Sets an ADDITIONAL function that is to be used at every 1549 timestep to display the iteration's progress. 1550 1551 Logically Collective on TS 1552 1553 Input Parameters: 1554 + ts - the TS context obtained from TSCreate() 1555 . func - monitoring routine 1556 . mctx - [optional] user-defined context for private data for the 1557 monitor routine (use PETSC_NULL if no context is desired) 1558 - monitordestroy - [optional] routine that frees monitor context 1559 (may be PETSC_NULL) 1560 1561 Calling sequence of func: 1562 $ int func(TS ts,PetscInt steps,PetscReal time,Vec x,void *mctx) 1563 1564 + ts - the TS context 1565 . steps - iteration number 1566 . time - current time 1567 . x - current iterate 1568 - mctx - [optional] monitoring context 1569 1570 Notes: 1571 This routine adds an additional monitor to the list of monitors that 1572 already has been loaded. 1573 1574 Fortran notes: Only a single monitor function can be set for each TS object 1575 1576 Level: intermediate 1577 1578 .keywords: TS, timestep, set, monitor 1579 1580 .seealso: TSMonitorDefault(), TSMonitorCancel() 1581 @*/ 1582 PetscErrorCode TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void*)) 1583 { 1584 PetscFunctionBegin; 1585 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1586 if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 1587 ts->monitor[ts->numbermonitors] = monitor; 1588 ts->mdestroy[ts->numbermonitors] = mdestroy; 1589 ts->monitorcontext[ts->numbermonitors++] = (void*)mctx; 1590 PetscFunctionReturn(0); 1591 } 1592 1593 #undef __FUNCT__ 1594 #define __FUNCT__ "TSMonitorCancel" 1595 /*@C 1596 TSMonitorCancel - Clears all the monitors that have been set on a time-step object. 1597 1598 Logically Collective on TS 1599 1600 Input Parameters: 1601 . ts - the TS context obtained from TSCreate() 1602 1603 Notes: 1604 There is no way to remove a single, specific monitor. 1605 1606 Level: intermediate 1607 1608 .keywords: TS, timestep, set, monitor 1609 1610 .seealso: TSMonitorDefault(), TSMonitorSet() 1611 @*/ 1612 PetscErrorCode TSMonitorCancel(TS ts) 1613 { 1614 PetscErrorCode ierr; 1615 PetscInt i; 1616 1617 PetscFunctionBegin; 1618 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1619 for (i=0; i<ts->numbermonitors; i++) { 1620 if (ts->mdestroy[i]) { 1621 ierr = (*ts->mdestroy[i])(ts->monitorcontext[i]);CHKERRQ(ierr); 1622 } 1623 } 1624 ts->numbermonitors = 0; 1625 PetscFunctionReturn(0); 1626 } 1627 1628 #undef __FUNCT__ 1629 #define __FUNCT__ "TSMonitorDefault" 1630 /*@ 1631 TSMonitorDefault - Sets the Default monitor 1632 1633 Level: intermediate 1634 1635 .keywords: TS, set, monitor 1636 1637 .seealso: TSMonitorDefault(), TSMonitorSet() 1638 @*/ 1639 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,void *ctx) 1640 { 1641 PetscErrorCode ierr; 1642 PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor)ctx; 1643 1644 PetscFunctionBegin; 1645 if (!ctx) { 1646 ierr = PetscViewerASCIIMonitorCreate(((PetscObject)ts)->comm,"stdout",0,&viewer);CHKERRQ(ierr); 1647 } 1648 ierr = PetscViewerASCIIMonitorPrintf(viewer,"%D TS dt %G time %G\n",step,ts->time_step,ptime);CHKERRQ(ierr); 1649 if (!ctx) { 1650 ierr = PetscViewerASCIIMonitorDestroy(viewer);CHKERRQ(ierr); 1651 } 1652 PetscFunctionReturn(0); 1653 } 1654 1655 #undef __FUNCT__ 1656 #define __FUNCT__ "TSStep" 1657 /*@ 1658 TSStep - Steps the requested number of timesteps. 1659 1660 Collective on TS 1661 1662 Input Parameter: 1663 . ts - the TS context obtained from TSCreate() 1664 1665 Output Parameters: 1666 + steps - number of iterations until termination 1667 - ptime - time until termination 1668 1669 Level: beginner 1670 1671 .keywords: TS, timestep, solve 1672 1673 .seealso: TSCreate(), TSSetUp(), TSDestroy() 1674 @*/ 1675 PetscErrorCode TSStep(TS ts,PetscInt *steps,PetscReal *ptime) 1676 { 1677 PetscErrorCode ierr; 1678 1679 PetscFunctionBegin; 1680 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1681 if (!ts->setupcalled) { 1682 ierr = TSSetUp(ts);CHKERRQ(ierr); 1683 } 1684 1685 ierr = PetscLogEventBegin(TS_Step, ts, 0, 0, 0);CHKERRQ(ierr); 1686 ierr = (*ts->ops->step)(ts, steps, ptime);CHKERRQ(ierr); 1687 ierr = PetscLogEventEnd(TS_Step, ts, 0, 0, 0);CHKERRQ(ierr); 1688 1689 if (!PetscPreLoadingOn) { 1690 ierr = TSViewFromOptions(ts,((PetscObject)ts)->name);CHKERRQ(ierr); 1691 } 1692 PetscFunctionReturn(0); 1693 } 1694 1695 #undef __FUNCT__ 1696 #define __FUNCT__ "TSSolve" 1697 /*@ 1698 TSSolve - Steps the requested number of timesteps. 1699 1700 Collective on TS 1701 1702 Input Parameter: 1703 + ts - the TS context obtained from TSCreate() 1704 - x - the solution vector, or PETSC_NULL if it was set with TSSetSolution() 1705 1706 Level: beginner 1707 1708 .keywords: TS, timestep, solve 1709 1710 .seealso: TSCreate(), TSSetSolution(), TSStep() 1711 @*/ 1712 PetscErrorCode TSSolve(TS ts, Vec x) 1713 { 1714 PetscInt steps; 1715 PetscReal ptime; 1716 PetscErrorCode ierr; 1717 1718 PetscFunctionBegin; 1719 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1720 /* set solution vector if provided */ 1721 if (x) { ierr = TSSetSolution(ts, x); CHKERRQ(ierr); } 1722 /* reset time step and iteration counters */ 1723 ts->steps = 0; ts->linear_its = 0; ts->nonlinear_its = 0; 1724 /* steps the requested number of timesteps. */ 1725 ierr = TSStep(ts, &steps, &ptime);CHKERRQ(ierr); 1726 PetscFunctionReturn(0); 1727 } 1728 1729 #undef __FUNCT__ 1730 #define __FUNCT__ "TSMonitor" 1731 /* 1732 Runs the user provided monitor routines, if they exists. 1733 */ 1734 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec x) 1735 { 1736 PetscErrorCode ierr; 1737 PetscInt i,n = ts->numbermonitors; 1738 1739 PetscFunctionBegin; 1740 for (i=0; i<n; i++) { 1741 ierr = (*ts->monitor[i])(ts,step,ptime,x,ts->monitorcontext[i]);CHKERRQ(ierr); 1742 } 1743 PetscFunctionReturn(0); 1744 } 1745 1746 /* ------------------------------------------------------------------------*/ 1747 1748 #undef __FUNCT__ 1749 #define __FUNCT__ "TSMonitorLGCreate" 1750 /*@C 1751 TSMonitorLGCreate - Creates a line graph context for use with 1752 TS to monitor convergence of preconditioned residual norms. 1753 1754 Collective on TS 1755 1756 Input Parameters: 1757 + host - the X display to open, or null for the local machine 1758 . label - the title to put in the title bar 1759 . x, y - the screen coordinates of the upper left coordinate of the window 1760 - m, n - the screen width and height in pixels 1761 1762 Output Parameter: 1763 . draw - the drawing context 1764 1765 Options Database Key: 1766 . -ts_monitor_draw - automatically sets line graph monitor 1767 1768 Notes: 1769 Use TSMonitorLGDestroy() to destroy this line graph, not PetscDrawLGDestroy(). 1770 1771 Level: intermediate 1772 1773 .keywords: TS, monitor, line graph, residual, seealso 1774 1775 .seealso: TSMonitorLGDestroy(), TSMonitorSet() 1776 1777 @*/ 1778 PetscErrorCode TSMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 1779 { 1780 PetscDraw win; 1781 PetscErrorCode ierr; 1782 1783 PetscFunctionBegin; 1784 ierr = PetscDrawCreate(PETSC_COMM_SELF,host,label,x,y,m,n,&win);CHKERRQ(ierr); 1785 ierr = PetscDrawSetType(win,PETSC_DRAW_X);CHKERRQ(ierr); 1786 ierr = PetscDrawLGCreate(win,1,draw);CHKERRQ(ierr); 1787 ierr = PetscDrawLGIndicateDataPoints(*draw);CHKERRQ(ierr); 1788 1789 ierr = PetscLogObjectParent(*draw,win);CHKERRQ(ierr); 1790 PetscFunctionReturn(0); 1791 } 1792 1793 #undef __FUNCT__ 1794 #define __FUNCT__ "TSMonitorLG" 1795 PetscErrorCode TSMonitorLG(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 1796 { 1797 PetscDrawLG lg = (PetscDrawLG) monctx; 1798 PetscReal x,y = ptime; 1799 PetscErrorCode ierr; 1800 1801 PetscFunctionBegin; 1802 if (!monctx) { 1803 MPI_Comm comm; 1804 PetscViewer viewer; 1805 1806 ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr); 1807 viewer = PETSC_VIEWER_DRAW_(comm); 1808 ierr = PetscViewerDrawGetDrawLG(viewer,0,&lg);CHKERRQ(ierr); 1809 } 1810 1811 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 1812 x = (PetscReal)n; 1813 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 1814 if (n < 20 || (n % 5)) { 1815 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 1816 } 1817 PetscFunctionReturn(0); 1818 } 1819 1820 #undef __FUNCT__ 1821 #define __FUNCT__ "TSMonitorLGDestroy" 1822 /*@C 1823 TSMonitorLGDestroy - Destroys a line graph context that was created 1824 with TSMonitorLGCreate(). 1825 1826 Collective on PetscDrawLG 1827 1828 Input Parameter: 1829 . draw - the drawing context 1830 1831 Level: intermediate 1832 1833 .keywords: TS, monitor, line graph, destroy 1834 1835 .seealso: TSMonitorLGCreate(), TSMonitorSet(), TSMonitorLG(); 1836 @*/ 1837 PetscErrorCode TSMonitorLGDestroy(PetscDrawLG drawlg) 1838 { 1839 PetscDraw draw; 1840 PetscErrorCode ierr; 1841 1842 PetscFunctionBegin; 1843 ierr = PetscDrawLGGetDraw(drawlg,&draw);CHKERRQ(ierr); 1844 ierr = PetscDrawDestroy(draw);CHKERRQ(ierr); 1845 ierr = PetscDrawLGDestroy(drawlg);CHKERRQ(ierr); 1846 PetscFunctionReturn(0); 1847 } 1848 1849 #undef __FUNCT__ 1850 #define __FUNCT__ "TSGetTime" 1851 /*@ 1852 TSGetTime - Gets the current time. 1853 1854 Not Collective 1855 1856 Input Parameter: 1857 . ts - the TS context obtained from TSCreate() 1858 1859 Output Parameter: 1860 . t - the current time 1861 1862 Level: beginner 1863 1864 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 1865 1866 .keywords: TS, get, time 1867 @*/ 1868 PetscErrorCode TSGetTime(TS ts,PetscReal* t) 1869 { 1870 PetscFunctionBegin; 1871 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1872 PetscValidDoublePointer(t,2); 1873 *t = ts->ptime; 1874 PetscFunctionReturn(0); 1875 } 1876 1877 #undef __FUNCT__ 1878 #define __FUNCT__ "TSSetTime" 1879 /*@ 1880 TSSetTime - Allows one to reset the time. 1881 1882 Logically Collective on TS 1883 1884 Input Parameters: 1885 + ts - the TS context obtained from TSCreate() 1886 - time - the time 1887 1888 Level: intermediate 1889 1890 .seealso: TSGetTime(), TSSetDuration() 1891 1892 .keywords: TS, set, time 1893 @*/ 1894 PetscErrorCode TSSetTime(TS ts, PetscReal t) 1895 { 1896 PetscFunctionBegin; 1897 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1898 PetscValidLogicalCollectiveReal(ts,t,2); 1899 ts->ptime = t; 1900 PetscFunctionReturn(0); 1901 } 1902 1903 #undef __FUNCT__ 1904 #define __FUNCT__ "TSSetOptionsPrefix" 1905 /*@C 1906 TSSetOptionsPrefix - Sets the prefix used for searching for all 1907 TS options in the database. 1908 1909 Logically Collective on TS 1910 1911 Input Parameter: 1912 + ts - The TS context 1913 - prefix - The prefix to prepend to all option names 1914 1915 Notes: 1916 A hyphen (-) must NOT be given at the beginning of the prefix name. 1917 The first character of all runtime options is AUTOMATICALLY the 1918 hyphen. 1919 1920 Level: advanced 1921 1922 .keywords: TS, set, options, prefix, database 1923 1924 .seealso: TSSetFromOptions() 1925 1926 @*/ 1927 PetscErrorCode TSSetOptionsPrefix(TS ts,const char prefix[]) 1928 { 1929 PetscErrorCode ierr; 1930 1931 PetscFunctionBegin; 1932 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1933 ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 1934 switch(ts->problem_type) { 1935 case TS_NONLINEAR: 1936 if (ts->snes) { 1937 ierr = SNESSetOptionsPrefix(ts->snes,prefix);CHKERRQ(ierr); 1938 } 1939 break; 1940 case TS_LINEAR: 1941 if (ts->ksp) { 1942 ierr = KSPSetOptionsPrefix(ts->ksp,prefix);CHKERRQ(ierr); 1943 } 1944 break; 1945 } 1946 PetscFunctionReturn(0); 1947 } 1948 1949 1950 #undef __FUNCT__ 1951 #define __FUNCT__ "TSAppendOptionsPrefix" 1952 /*@C 1953 TSAppendOptionsPrefix - Appends to the prefix used for searching for all 1954 TS options in the database. 1955 1956 Logically Collective on TS 1957 1958 Input Parameter: 1959 + ts - The TS context 1960 - prefix - The prefix to prepend to all option names 1961 1962 Notes: 1963 A hyphen (-) must NOT be given at the beginning of the prefix name. 1964 The first character of all runtime options is AUTOMATICALLY the 1965 hyphen. 1966 1967 Level: advanced 1968 1969 .keywords: TS, append, options, prefix, database 1970 1971 .seealso: TSGetOptionsPrefix() 1972 1973 @*/ 1974 PetscErrorCode TSAppendOptionsPrefix(TS ts,const char prefix[]) 1975 { 1976 PetscErrorCode ierr; 1977 1978 PetscFunctionBegin; 1979 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1980 ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 1981 switch(ts->problem_type) { 1982 case TS_NONLINEAR: 1983 if (ts->snes) { 1984 ierr = SNESAppendOptionsPrefix(ts->snes,prefix);CHKERRQ(ierr); 1985 } 1986 break; 1987 case TS_LINEAR: 1988 if (ts->ksp) { 1989 ierr = KSPAppendOptionsPrefix(ts->ksp,prefix);CHKERRQ(ierr); 1990 } 1991 break; 1992 } 1993 PetscFunctionReturn(0); 1994 } 1995 1996 #undef __FUNCT__ 1997 #define __FUNCT__ "TSGetOptionsPrefix" 1998 /*@C 1999 TSGetOptionsPrefix - Sets the prefix used for searching for all 2000 TS options in the database. 2001 2002 Not Collective 2003 2004 Input Parameter: 2005 . ts - The TS context 2006 2007 Output Parameter: 2008 . prefix - A pointer to the prefix string used 2009 2010 Notes: On the fortran side, the user should pass in a string 'prifix' of 2011 sufficient length to hold the prefix. 2012 2013 Level: intermediate 2014 2015 .keywords: TS, get, options, prefix, database 2016 2017 .seealso: TSAppendOptionsPrefix() 2018 @*/ 2019 PetscErrorCode TSGetOptionsPrefix(TS ts,const char *prefix[]) 2020 { 2021 PetscErrorCode ierr; 2022 2023 PetscFunctionBegin; 2024 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2025 PetscValidPointer(prefix,2); 2026 ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 2027 PetscFunctionReturn(0); 2028 } 2029 2030 #undef __FUNCT__ 2031 #define __FUNCT__ "TSGetRHSJacobian" 2032 /*@C 2033 TSGetRHSJacobian - Returns the Jacobian J at the present timestep. 2034 2035 Not Collective, but parallel objects are returned if TS is parallel 2036 2037 Input Parameter: 2038 . ts - The TS context obtained from TSCreate() 2039 2040 Output Parameters: 2041 + J - The Jacobian J of F, where U_t = F(U,t) 2042 . M - The preconditioner matrix, usually the same as J 2043 - ctx - User-defined context for Jacobian evaluation routine 2044 2045 Notes: You can pass in PETSC_NULL for any return argument you do not need. 2046 2047 Level: intermediate 2048 2049 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 2050 2051 .keywords: TS, timestep, get, matrix, Jacobian 2052 @*/ 2053 PetscErrorCode TSGetRHSJacobian(TS ts,Mat *J,Mat *M,void **ctx) 2054 { 2055 PetscFunctionBegin; 2056 if (J) *J = ts->Arhs; 2057 if (M) *M = ts->B; 2058 if (ctx) *ctx = ts->jacP; 2059 PetscFunctionReturn(0); 2060 } 2061 2062 #undef __FUNCT__ 2063 #define __FUNCT__ "TSGetIJacobian" 2064 /*@C 2065 TSGetIJacobian - Returns the implicit Jacobian at the present timestep. 2066 2067 Not Collective, but parallel objects are returned if TS is parallel 2068 2069 Input Parameter: 2070 . ts - The TS context obtained from TSCreate() 2071 2072 Output Parameters: 2073 + A - The Jacobian of F(t,U,U_t) 2074 . B - The preconditioner matrix, often the same as A 2075 . f - The function to compute the matrices 2076 - ctx - User-defined context for Jacobian evaluation routine 2077 2078 Notes: You can pass in PETSC_NULL for any return argument you do not need. 2079 2080 Level: advanced 2081 2082 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 2083 2084 .keywords: TS, timestep, get, matrix, Jacobian 2085 @*/ 2086 PetscErrorCode TSGetIJacobian(TS ts,Mat *A,Mat *B,TSIJacobian *f,void **ctx) 2087 { 2088 PetscFunctionBegin; 2089 if (A) *A = ts->A; 2090 if (B) *B = ts->B; 2091 if (f) *f = ts->ops->ijacobian; 2092 if (ctx) *ctx = ts->jacP; 2093 PetscFunctionReturn(0); 2094 } 2095 2096 #undef __FUNCT__ 2097 #define __FUNCT__ "TSMonitorSolution" 2098 /*@C 2099 TSMonitorSolution - Monitors progress of the TS solvers by calling 2100 VecView() for the solution at each timestep 2101 2102 Collective on TS 2103 2104 Input Parameters: 2105 + ts - the TS context 2106 . step - current time-step 2107 . ptime - current time 2108 - dummy - either a viewer or PETSC_NULL 2109 2110 Level: intermediate 2111 2112 .keywords: TS, vector, monitor, view 2113 2114 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 2115 @*/ 2116 PetscErrorCode TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec x,void *dummy) 2117 { 2118 PetscErrorCode ierr; 2119 PetscViewer viewer = (PetscViewer) dummy; 2120 2121 PetscFunctionBegin; 2122 if (!dummy) { 2123 viewer = PETSC_VIEWER_DRAW_(((PetscObject)ts)->comm); 2124 } 2125 ierr = VecView(x,viewer);CHKERRQ(ierr); 2126 PetscFunctionReturn(0); 2127 } 2128 2129 2130 #undef __FUNCT__ 2131 #define __FUNCT__ "TSSetDM" 2132 /*@ 2133 TSSetDM - Sets the DM that may be used by some preconditioners 2134 2135 Logically Collective on TS and DM 2136 2137 Input Parameters: 2138 + ts - the preconditioner context 2139 - dm - the dm 2140 2141 Level: intermediate 2142 2143 2144 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM() 2145 @*/ 2146 PetscErrorCode TSSetDM(TS ts,DM dm) 2147 { 2148 PetscErrorCode ierr; 2149 2150 PetscFunctionBegin; 2151 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2152 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 2153 if (ts->dm) {ierr = DMDestroy(ts->dm);CHKERRQ(ierr);} 2154 ts->dm = dm; 2155 if (ts->snes) { 2156 ierr = SNESSetDM(ts->snes,dm);CHKERRQ(ierr); 2157 } 2158 if (ts->ksp) { 2159 ierr = KSPSetDM(ts->ksp,dm);CHKERRQ(ierr); 2160 ierr = KSPSetDMActive(ts->ksp,PETSC_FALSE);CHKERRQ(ierr); 2161 } 2162 PetscFunctionReturn(0); 2163 } 2164 2165 #undef __FUNCT__ 2166 #define __FUNCT__ "TSGetDM" 2167 /*@ 2168 TSGetDM - Gets the DM that may be used by some preconditioners 2169 2170 Not Collective 2171 2172 Input Parameter: 2173 . ts - the preconditioner context 2174 2175 Output Parameter: 2176 . dm - the dm 2177 2178 Level: intermediate 2179 2180 2181 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM() 2182 @*/ 2183 PetscErrorCode TSGetDM(TS ts,DM *dm) 2184 { 2185 PetscFunctionBegin; 2186 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2187 *dm = ts->dm; 2188 PetscFunctionReturn(0); 2189 } 2190 2191 #undef __FUNCT__ 2192 #define __FUNCT__ "SNESTSFormFunction" 2193 /*@ 2194 SNESTSFormFunction - Function to evaluate nonlinear residual 2195 2196 Logically Collective on SNES 2197 2198 Input Parameter: 2199 + snes - nonlinear solver 2200 . X - the current state at which to evaluate the residual 2201 - ctx - user context, must be a TS 2202 2203 Output Parameter: 2204 . F - the nonlinear residual 2205 2206 Notes: 2207 This function is not normally called by users and is automatically registered with the SNES used by TS. 2208 It is most frequently passed to MatFDColoringSetFunction(). 2209 2210 Level: advanced 2211 2212 .seealso: SNESSetFunction(), MatFDColoringSetFunction() 2213 @*/ 2214 PetscErrorCode SNESTSFormFunction(SNES snes,Vec X,Vec F,void *ctx) 2215 { 2216 TS ts = (TS)ctx; 2217 PetscErrorCode ierr; 2218 2219 PetscFunctionBegin; 2220 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2221 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2222 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 2223 PetscValidHeaderSpecific(ts,TS_CLASSID,4); 2224 ierr = (ts->ops->snesfunction)(snes,X,F,ts);CHKERRQ(ierr); 2225 PetscFunctionReturn(0); 2226 } 2227 2228 #undef __FUNCT__ 2229 #define __FUNCT__ "SNESTSFormJacobian" 2230 /*@ 2231 SNESTSFormJacobian - Function to evaluate the Jacobian 2232 2233 Collective on SNES 2234 2235 Input Parameter: 2236 + snes - nonlinear solver 2237 . X - the current state at which to evaluate the residual 2238 - ctx - user context, must be a TS 2239 2240 Output Parameter: 2241 + A - the Jacobian 2242 . B - the preconditioning matrix (may be the same as A) 2243 - flag - indicates any structure change in the matrix 2244 2245 Notes: 2246 This function is not normally called by users and is automatically registered with the SNES used by TS. 2247 2248 Level: developer 2249 2250 .seealso: SNESSetJacobian() 2251 @*/ 2252 PetscErrorCode SNESTSFormJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flag,void *ctx) 2253 { 2254 TS ts = (TS)ctx; 2255 PetscErrorCode ierr; 2256 2257 PetscFunctionBegin; 2258 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2259 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2260 PetscValidPointer(A,3); 2261 PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 2262 PetscValidPointer(B,4); 2263 PetscValidHeaderSpecific(*B,MAT_CLASSID,4); 2264 PetscValidPointer(flag,5); 2265 PetscValidHeaderSpecific(ts,TS_CLASSID,6); 2266 ierr = (ts->ops->snesjacobian)(snes,X,A,B,flag,ts);CHKERRQ(ierr); 2267 PetscFunctionReturn(0); 2268 } 2269 2270 #if defined(PETSC_HAVE_MATLAB_ENGINE) 2271 #include <mex.h> 2272 2273 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext; 2274 2275 #undef __FUNCT__ 2276 #define __FUNCT__ "TSComputeFunction_Matlab" 2277 /* 2278 TSComputeFunction_Matlab - Calls the function that has been set with 2279 TSSetFunctionMatlab(). 2280 2281 Collective on TS 2282 2283 Input Parameters: 2284 + snes - the TS context 2285 - x - input vector 2286 2287 Output Parameter: 2288 . y - function vector, as set by TSSetFunction() 2289 2290 Notes: 2291 TSComputeFunction() is typically used within nonlinear solvers 2292 implementations, so most users would not generally call this routine 2293 themselves. 2294 2295 Level: developer 2296 2297 .keywords: TS, nonlinear, compute, function 2298 2299 .seealso: TSSetFunction(), TSGetFunction() 2300 */ 2301 PetscErrorCode TSComputeFunction_Matlab(TS snes,PetscReal time,Vec x,Vec xdot,Vec y, void *ctx) 2302 { 2303 PetscErrorCode ierr; 2304 TSMatlabContext *sctx = (TSMatlabContext *)ctx; 2305 int nlhs = 1,nrhs = 7; 2306 mxArray *plhs[1],*prhs[7]; 2307 long long int lx = 0,lxdot = 0,ly = 0,ls = 0; 2308 2309 PetscFunctionBegin; 2310 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 2311 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 2312 PetscValidHeaderSpecific(xdot,VEC_CLASSID,4); 2313 PetscValidHeaderSpecific(y,VEC_CLASSID,5); 2314 PetscCheckSameComm(snes,1,x,3); 2315 PetscCheckSameComm(snes,1,y,5); 2316 2317 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 2318 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 2319 ierr = PetscMemcpy(&lxdot,&xdot,sizeof(xdot));CHKERRQ(ierr); 2320 ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 2321 prhs[0] = mxCreateDoubleScalar((double)ls); 2322 prhs[1] = mxCreateDoubleScalar(time); 2323 prhs[2] = mxCreateDoubleScalar((double)lx); 2324 prhs[3] = mxCreateDoubleScalar((double)lxdot); 2325 prhs[4] = mxCreateDoubleScalar((double)ly); 2326 prhs[5] = mxCreateString(sctx->funcname); 2327 prhs[6] = sctx->ctx; 2328 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr); 2329 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 2330 mxDestroyArray(prhs[0]); 2331 mxDestroyArray(prhs[1]); 2332 mxDestroyArray(prhs[2]); 2333 mxDestroyArray(prhs[3]); 2334 mxDestroyArray(prhs[4]); 2335 mxDestroyArray(prhs[5]); 2336 mxDestroyArray(plhs[0]); 2337 PetscFunctionReturn(0); 2338 } 2339 2340 2341 #undef __FUNCT__ 2342 #define __FUNCT__ "TSSetFunctionMatlab" 2343 /* 2344 TSSetFunctionMatlab - Sets the function evaluation routine and function 2345 vector for use by the TS routines in solving ODEs 2346 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 2347 2348 Logically Collective on TS 2349 2350 Input Parameters: 2351 + ts - the TS context 2352 - func - function evaluation routine 2353 2354 Calling sequence of func: 2355 $ func (TS ts,PetscReal time,Vec x,Vec xdot,Vec f,void *ctx); 2356 2357 Level: beginner 2358 2359 .keywords: TS, nonlinear, set, function 2360 2361 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 2362 */ 2363 PetscErrorCode TSSetFunctionMatlab(TS snes,const char *func,mxArray *ctx) 2364 { 2365 PetscErrorCode ierr; 2366 TSMatlabContext *sctx; 2367 2368 PetscFunctionBegin; 2369 /* currently sctx is memory bleed */ 2370 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 2371 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 2372 /* 2373 This should work, but it doesn't 2374 sctx->ctx = ctx; 2375 mexMakeArrayPersistent(sctx->ctx); 2376 */ 2377 sctx->ctx = mxDuplicateArray(ctx); 2378 ierr = TSSetIFunction(snes,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr); 2379 PetscFunctionReturn(0); 2380 } 2381 2382 #undef __FUNCT__ 2383 #define __FUNCT__ "TSComputeJacobian_Matlab" 2384 /* 2385 TSComputeJacobian_Matlab - Calls the function that has been set with 2386 TSSetJacobianMatlab(). 2387 2388 Collective on TS 2389 2390 Input Parameters: 2391 + snes - the TS context 2392 . x - input vector 2393 . A, B - the matrices 2394 - ctx - user context 2395 2396 Output Parameter: 2397 . flag - structure of the matrix 2398 2399 Level: developer 2400 2401 .keywords: TS, nonlinear, compute, function 2402 2403 .seealso: TSSetFunction(), TSGetFunction() 2404 @*/ 2405 PetscErrorCode TSComputeJacobian_Matlab(TS snes,PetscReal time,Vec x,Vec xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flag, void *ctx) 2406 { 2407 PetscErrorCode ierr; 2408 TSMatlabContext *sctx = (TSMatlabContext *)ctx; 2409 int nlhs = 2,nrhs = 9; 2410 mxArray *plhs[2],*prhs[9]; 2411 long long int lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0; 2412 2413 PetscFunctionBegin; 2414 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 2415 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 2416 2417 /* call Matlab function in ctx with arguments x and y */ 2418 2419 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 2420 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 2421 ierr = PetscMemcpy(&lxdot,&xdot,sizeof(x));CHKERRQ(ierr); 2422 ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 2423 ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 2424 prhs[0] = mxCreateDoubleScalar((double)ls); 2425 prhs[1] = mxCreateDoubleScalar((double)time); 2426 prhs[2] = mxCreateDoubleScalar((double)lx); 2427 prhs[3] = mxCreateDoubleScalar((double)lxdot); 2428 prhs[4] = mxCreateDoubleScalar((double)shift); 2429 prhs[5] = mxCreateDoubleScalar((double)lA); 2430 prhs[6] = mxCreateDoubleScalar((double)lB); 2431 prhs[7] = mxCreateString(sctx->funcname); 2432 prhs[8] = sctx->ctx; 2433 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr); 2434 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 2435 *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 2436 mxDestroyArray(prhs[0]); 2437 mxDestroyArray(prhs[1]); 2438 mxDestroyArray(prhs[2]); 2439 mxDestroyArray(prhs[3]); 2440 mxDestroyArray(prhs[4]); 2441 mxDestroyArray(prhs[5]); 2442 mxDestroyArray(prhs[6]); 2443 mxDestroyArray(prhs[7]); 2444 mxDestroyArray(plhs[0]); 2445 mxDestroyArray(plhs[1]); 2446 PetscFunctionReturn(0); 2447 } 2448 2449 2450 #undef __FUNCT__ 2451 #define __FUNCT__ "TSSetJacobianMatlab" 2452 /* 2453 TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 2454 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 2455 2456 Logically Collective on TS 2457 2458 Input Parameters: 2459 + snes - the TS context 2460 . A,B - Jacobian matrices 2461 . func - function evaluation routine 2462 - ctx - user context 2463 2464 Calling sequence of func: 2465 $ flag = func (TS snes,PetscReal time,Vec x,Vec xdot,Mat A,Mat B,void *ctx); 2466 2467 2468 Level: developer 2469 2470 .keywords: TS, nonlinear, set, function 2471 2472 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 2473 */ 2474 PetscErrorCode TSSetJacobianMatlab(TS snes,Mat A,Mat B,const char *func,mxArray *ctx) 2475 { 2476 PetscErrorCode ierr; 2477 TSMatlabContext *sctx; 2478 2479 PetscFunctionBegin; 2480 /* currently sctx is memory bleed */ 2481 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 2482 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 2483 /* 2484 This should work, but it doesn't 2485 sctx->ctx = ctx; 2486 mexMakeArrayPersistent(sctx->ctx); 2487 */ 2488 sctx->ctx = mxDuplicateArray(ctx); 2489 ierr = TSSetIJacobian(snes,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 2490 PetscFunctionReturn(0); 2491 } 2492 2493 #undef __FUNCT__ 2494 #define __FUNCT__ "TSMonitor_Matlab" 2495 /* 2496 TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab(). 2497 2498 Collective on TS 2499 2500 .seealso: TSSetFunction(), TSGetFunction() 2501 @*/ 2502 PetscErrorCode TSMonitor_Matlab(TS snes,PetscInt it, PetscReal time,Vec x, void *ctx) 2503 { 2504 PetscErrorCode ierr; 2505 TSMatlabContext *sctx = (TSMatlabContext *)ctx; 2506 int nlhs = 1,nrhs = 6; 2507 mxArray *plhs[1],*prhs[6]; 2508 long long int lx = 0,ls = 0; 2509 2510 PetscFunctionBegin; 2511 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 2512 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 2513 2514 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 2515 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 2516 prhs[0] = mxCreateDoubleScalar((double)ls); 2517 prhs[1] = mxCreateDoubleScalar((double)it); 2518 prhs[2] = mxCreateDoubleScalar((double)time); 2519 prhs[3] = mxCreateDoubleScalar((double)lx); 2520 prhs[4] = mxCreateString(sctx->funcname); 2521 prhs[5] = sctx->ctx; 2522 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr); 2523 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 2524 mxDestroyArray(prhs[0]); 2525 mxDestroyArray(prhs[1]); 2526 mxDestroyArray(prhs[2]); 2527 mxDestroyArray(prhs[3]); 2528 mxDestroyArray(prhs[4]); 2529 mxDestroyArray(plhs[0]); 2530 PetscFunctionReturn(0); 2531 } 2532 2533 2534 #undef __FUNCT__ 2535 #define __FUNCT__ "TSMonitorSetMatlab" 2536 /* 2537 TSMonitorSetMatlab - Sets the monitor function from Matlab 2538 2539 Level: developer 2540 2541 .keywords: TS, nonlinear, set, function 2542 2543 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 2544 */ 2545 PetscErrorCode TSMonitorSetMatlab(TS snes,const char *func,mxArray *ctx) 2546 { 2547 PetscErrorCode ierr; 2548 TSMatlabContext *sctx; 2549 2550 PetscFunctionBegin; 2551 /* currently sctx is memory bleed */ 2552 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 2553 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 2554 /* 2555 This should work, but it doesn't 2556 sctx->ctx = ctx; 2557 mexMakeArrayPersistent(sctx->ctx); 2558 */ 2559 sctx->ctx = mxDuplicateArray(ctx); 2560 ierr = TSMonitorSet(snes,TSMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 2561 PetscFunctionReturn(0); 2562 } 2563 2564 #endif 2565