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