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