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 = PetscOptionsBegin(((PetscObject)ts)->comm, ((PetscObject)ts)->prefix, "Time step options", "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","TSSetInitialTime", ts->ptime, &ts->ptime, PETSC_NULL);CHKERRQ(ierr); 90 ierr = PetscOptionsReal("-ts_dt","Initial time step","TSSetInitialTimeStep",ts->initial_time_step,&dt,&opt);CHKERRQ(ierr); 91 if (opt) {ierr = TSSetInitialTimeStep(ts,ts->ptime,dt);CHKERRQ(ierr);} 92 opt = ts->exact_final_time == PETSC_DECIDE ? PETSC_FALSE : (PetscBool)ts->exact_final_time; 93 ierr = PetscOptionsBool("-ts_exact_final_time","Interpolate output to stop exactly at the final time","TSSetExactFinalTime",opt,&opt,&flg);CHKERRQ(ierr); 94 if (flg) {ierr = TSSetExactFinalTime(ts,opt);CHKERRQ(ierr);} 95 ierr = PetscOptionsInt("-ts_max_snes_failures","Maximum number of nonlinear solve failures","",ts->max_snes_failures,&ts->max_snes_failures,PETSC_NULL);CHKERRQ(ierr); 96 ierr = PetscOptionsInt("-ts_max_reject","Maximum number of step rejections","",ts->max_reject,&ts->max_reject,PETSC_NULL);CHKERRQ(ierr); 97 ierr = PetscOptionsBool("-ts_error_if_step_failed","Error if no step succeeds","",ts->errorifstepfailed,&ts->errorifstepfailed,PETSC_NULL);CHKERRQ(ierr); 98 99 /* Monitor options */ 100 ierr = PetscOptionsString("-ts_monitor","Monitor timestep size","TSMonitorDefault","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 101 if (flg) { 102 ierr = PetscViewerASCIIOpen(((PetscObject)ts)->comm,monfilename,&monviewer);CHKERRQ(ierr); 103 ierr = TSMonitorSet(ts,TSMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 104 } 105 ierr = PetscOptionsString("-ts_monitor_python","Use Python function","TSMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 106 if (flg) {ierr = PetscPythonMonitorSet((PetscObject)ts,monfilename);CHKERRQ(ierr);} 107 108 opt = PETSC_FALSE; 109 ierr = PetscOptionsBool("-ts_monitor_draw","Monitor timestep size graphically","TSMonitorLG",opt,&opt,PETSC_NULL);CHKERRQ(ierr); 110 if (opt) { 111 ierr = TSMonitorSet(ts,TSMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 112 } 113 opt = PETSC_FALSE; 114 ierr = PetscOptionsBool("-ts_monitor_solution","Monitor solution graphically","TSMonitorSolution",opt,&opt,PETSC_NULL);CHKERRQ(ierr); 115 if (opt) { 116 void *ctx; 117 ierr = TSMonitorSolutionCreate(ts,PETSC_NULL,&ctx);CHKERRQ(ierr); 118 ierr = TSMonitorSet(ts,TSMonitorSolution,ctx,TSMonitorSolutionDestroy);CHKERRQ(ierr); 119 } 120 121 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 122 if (ts->problem_type == TS_LINEAR) {ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);} 123 ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); 124 125 /* Handle specific TS options */ 126 if (ts->ops->setfromoptions) { 127 ierr = (*ts->ops->setfromoptions)(ts);CHKERRQ(ierr); 128 } 129 130 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 131 ierr = PetscObjectProcessOptionsHandlers((PetscObject)ts);CHKERRQ(ierr); 132 ierr = PetscOptionsEnd();CHKERRQ(ierr); 133 PetscFunctionReturn(0); 134 } 135 136 #undef __FUNCT__ 137 #undef __FUNCT__ 138 #define __FUNCT__ "TSComputeRHSJacobian" 139 /*@ 140 TSComputeRHSJacobian - Computes the Jacobian matrix that has been 141 set with TSSetRHSJacobian(). 142 143 Collective on TS and Vec 144 145 Input Parameters: 146 + ts - the TS context 147 . t - current timestep 148 - x - input vector 149 150 Output Parameters: 151 + A - Jacobian matrix 152 . B - optional preconditioning matrix 153 - flag - flag indicating matrix structure 154 155 Notes: 156 Most users should not need to explicitly call this routine, as it 157 is used internally within the nonlinear solvers. 158 159 See KSPSetOperators() for important information about setting the 160 flag parameter. 161 162 Level: developer 163 164 .keywords: SNES, compute, Jacobian, matrix 165 166 .seealso: TSSetRHSJacobian(), KSPSetOperators() 167 @*/ 168 PetscErrorCode TSComputeRHSJacobian(TS ts,PetscReal t,Vec X,Mat *A,Mat *B,MatStructure *flg) 169 { 170 PetscErrorCode ierr; 171 PetscInt Xstate; 172 173 PetscFunctionBegin; 174 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 175 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 176 PetscCheckSameComm(ts,1,X,3); 177 ierr = PetscObjectStateQuery((PetscObject)X,&Xstate);CHKERRQ(ierr); 178 if (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.X == X && ts->rhsjacobian.Xstate == Xstate))) { 179 *flg = ts->rhsjacobian.mstructure; 180 PetscFunctionReturn(0); 181 } 182 183 if (!ts->userops->rhsjacobian && !ts->userops->ijacobian) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()"); 184 185 if (ts->userops->rhsjacobian) { 186 ierr = PetscLogEventBegin(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr); 187 *flg = DIFFERENT_NONZERO_PATTERN; 188 PetscStackPush("TS user Jacobian function"); 189 ierr = (*ts->userops->rhsjacobian)(ts,t,X,A,B,flg,ts->jacP);CHKERRQ(ierr); 190 PetscStackPop; 191 ierr = PetscLogEventEnd(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr); 192 /* make sure user returned a correct Jacobian and preconditioner */ 193 PetscValidHeaderSpecific(*A,MAT_CLASSID,4); 194 PetscValidHeaderSpecific(*B,MAT_CLASSID,5); 195 } else { 196 ierr = MatZeroEntries(*A);CHKERRQ(ierr); 197 if (*A != *B) {ierr = MatZeroEntries(*B);CHKERRQ(ierr);} 198 *flg = SAME_NONZERO_PATTERN; 199 } 200 ts->rhsjacobian.time = t; 201 ts->rhsjacobian.X = X; 202 ierr = PetscObjectStateQuery((PetscObject)X,&ts->rhsjacobian.Xstate);CHKERRQ(ierr); 203 ts->rhsjacobian.mstructure = *flg; 204 PetscFunctionReturn(0); 205 } 206 207 #undef __FUNCT__ 208 #define __FUNCT__ "TSComputeRHSFunction" 209 /*@ 210 TSComputeRHSFunction - Evaluates the right-hand-side function. 211 212 Collective on TS and Vec 213 214 Input Parameters: 215 + ts - the TS context 216 . t - current time 217 - x - state vector 218 219 Output Parameter: 220 . y - right hand side 221 222 Note: 223 Most users should not need to explicitly call this routine, as it 224 is used internally within the nonlinear solvers. 225 226 Level: developer 227 228 .keywords: TS, compute 229 230 .seealso: TSSetRHSFunction(), TSComputeIFunction() 231 @*/ 232 PetscErrorCode TSComputeRHSFunction(TS ts,PetscReal t,Vec x,Vec y) 233 { 234 PetscErrorCode ierr; 235 236 PetscFunctionBegin; 237 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 238 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 239 PetscValidHeaderSpecific(y,VEC_CLASSID,4); 240 241 if (!ts->userops->rhsfunction && !ts->userops->ifunction) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 242 243 ierr = PetscLogEventBegin(TS_FunctionEval,ts,x,y,0);CHKERRQ(ierr); 244 if (ts->userops->rhsfunction) { 245 PetscStackPush("TS user right-hand-side function"); 246 ierr = (*ts->userops->rhsfunction)(ts,t,x,y,ts->funP);CHKERRQ(ierr); 247 PetscStackPop; 248 } else { 249 ierr = VecZeroEntries(y);CHKERRQ(ierr); 250 } 251 252 ierr = PetscLogEventEnd(TS_FunctionEval,ts,x,y,0);CHKERRQ(ierr); 253 PetscFunctionReturn(0); 254 } 255 256 #undef __FUNCT__ 257 #define __FUNCT__ "TSGetRHSVec_Private" 258 static PetscErrorCode TSGetRHSVec_Private(TS ts,Vec *Frhs) 259 { 260 Vec F; 261 PetscErrorCode ierr; 262 263 PetscFunctionBegin; 264 *Frhs = PETSC_NULL; 265 ierr = TSGetIFunction(ts,&F,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 266 if (!ts->Frhs) { 267 ierr = VecDuplicate(F,&ts->Frhs);CHKERRQ(ierr); 268 } 269 *Frhs = ts->Frhs; 270 PetscFunctionReturn(0); 271 } 272 273 #undef __FUNCT__ 274 #define __FUNCT__ "TSGetRHSMats_Private" 275 static PetscErrorCode TSGetRHSMats_Private(TS ts,Mat *Arhs,Mat *Brhs) 276 { 277 Mat A,B; 278 PetscErrorCode ierr; 279 280 PetscFunctionBegin; 281 ierr = TSGetIJacobian(ts,&A,&B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 282 if (Arhs) { 283 if (!ts->Arhs) { 284 ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&ts->Arhs);CHKERRQ(ierr); 285 } 286 *Arhs = ts->Arhs; 287 } 288 if (Brhs) { 289 if (!ts->Brhs) { 290 ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&ts->Brhs);CHKERRQ(ierr); 291 } 292 *Brhs = ts->Brhs; 293 } 294 PetscFunctionReturn(0); 295 } 296 297 #undef __FUNCT__ 298 #define __FUNCT__ "TSComputeIFunction" 299 /*@ 300 TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,X,Xdot)=0 301 302 Collective on TS and Vec 303 304 Input Parameters: 305 + ts - the TS context 306 . t - current time 307 . X - state vector 308 . Xdot - time derivative of state vector 309 - imex - flag indicates if the method is IMEX so that the RHSFunction should be kept separate 310 311 Output Parameter: 312 . Y - right hand side 313 314 Note: 315 Most users should not need to explicitly call this routine, as it 316 is used internally within the nonlinear solvers. 317 318 If the user did did not write their equations in implicit form, this 319 function recasts them in implicit form. 320 321 Level: developer 322 323 .keywords: TS, compute 324 325 .seealso: TSSetIFunction(), TSComputeRHSFunction() 326 @*/ 327 PetscErrorCode TSComputeIFunction(TS ts,PetscReal t,Vec X,Vec Xdot,Vec Y,PetscBool imex) 328 { 329 PetscErrorCode ierr; 330 331 PetscFunctionBegin; 332 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 333 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 334 PetscValidHeaderSpecific(Xdot,VEC_CLASSID,4); 335 PetscValidHeaderSpecific(Y,VEC_CLASSID,5); 336 337 if (!ts->userops->rhsfunction && !ts->userops->ifunction) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 338 339 ierr = PetscLogEventBegin(TS_FunctionEval,ts,X,Xdot,Y);CHKERRQ(ierr); 340 if (ts->userops->ifunction) { 341 PetscStackPush("TS user implicit function"); 342 ierr = (*ts->userops->ifunction)(ts,t,X,Xdot,Y,ts->funP);CHKERRQ(ierr); 343 PetscStackPop; 344 } 345 if (imex) { 346 if (!ts->userops->ifunction) { 347 ierr = VecCopy(Xdot,Y);CHKERRQ(ierr); 348 } 349 } else if (ts->userops->rhsfunction) { 350 if (ts->userops->ifunction) { 351 Vec Frhs; 352 ierr = TSGetRHSVec_Private(ts,&Frhs);CHKERRQ(ierr); 353 ierr = TSComputeRHSFunction(ts,t,X,Frhs);CHKERRQ(ierr); 354 ierr = VecAXPY(Y,-1,Frhs);CHKERRQ(ierr); 355 } else { 356 ierr = TSComputeRHSFunction(ts,t,X,Y);CHKERRQ(ierr); 357 ierr = VecAYPX(Y,-1,Xdot);CHKERRQ(ierr); 358 } 359 } 360 ierr = PetscLogEventEnd(TS_FunctionEval,ts,X,Xdot,Y);CHKERRQ(ierr); 361 PetscFunctionReturn(0); 362 } 363 364 #undef __FUNCT__ 365 #define __FUNCT__ "TSComputeIJacobian" 366 /*@ 367 TSComputeIJacobian - Evaluates the Jacobian of the DAE 368 369 Collective on TS and Vec 370 371 Input 372 Input Parameters: 373 + ts - the TS context 374 . t - current timestep 375 . X - state vector 376 . Xdot - time derivative of state vector 377 . shift - shift to apply, see note below 378 - imex - flag indicates if the method is IMEX so that the RHSJacobian should be kept separate 379 380 Output Parameters: 381 + A - Jacobian matrix 382 . B - optional preconditioning matrix 383 - flag - flag indicating matrix structure 384 385 Notes: 386 If F(t,X,Xdot)=0 is the DAE, the required Jacobian is 387 388 dF/dX + shift*dF/dXdot 389 390 Most users should not need to explicitly call this routine, as it 391 is used internally within the nonlinear solvers. 392 393 Level: developer 394 395 .keywords: TS, compute, Jacobian, matrix 396 397 .seealso: TSSetIJacobian() 398 @*/ 399 PetscErrorCode TSComputeIJacobian(TS ts,PetscReal t,Vec X,Vec Xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,PetscBool imex) 400 { 401 PetscInt Xstate, Xdotstate; 402 PetscErrorCode ierr; 403 404 PetscFunctionBegin; 405 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 406 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 407 PetscValidHeaderSpecific(Xdot,VEC_CLASSID,4); 408 PetscValidPointer(A,6); 409 PetscValidHeaderSpecific(*A,MAT_CLASSID,6); 410 PetscValidPointer(B,7); 411 PetscValidHeaderSpecific(*B,MAT_CLASSID,7); 412 PetscValidPointer(flg,8); 413 ierr = PetscObjectStateQuery((PetscObject)X,&Xstate);CHKERRQ(ierr); 414 ierr = PetscObjectStateQuery((PetscObject)Xdot,&Xdotstate);CHKERRQ(ierr); 415 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))) { 416 *flg = ts->ijacobian.mstructure; 417 ierr = MatScale(*A, shift / ts->ijacobian.shift);CHKERRQ(ierr); 418 PetscFunctionReturn(0); 419 } 420 421 if (!ts->userops->rhsjacobian && !ts->userops->ijacobian) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()"); 422 423 *flg = SAME_NONZERO_PATTERN; /* In case we're solving a linear problem in which case it wouldn't get initialized below. */ 424 ierr = PetscLogEventBegin(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr); 425 if (ts->userops->ijacobian) { 426 *flg = DIFFERENT_NONZERO_PATTERN; 427 PetscStackPush("TS user implicit Jacobian"); 428 ierr = (*ts->userops->ijacobian)(ts,t,X,Xdot,shift,A,B,flg,ts->jacP);CHKERRQ(ierr); 429 PetscStackPop; 430 /* make sure user returned a correct Jacobian and preconditioner */ 431 PetscValidHeaderSpecific(*A,MAT_CLASSID,4); 432 PetscValidHeaderSpecific(*B,MAT_CLASSID,5); 433 } 434 if (imex) { 435 if (!ts->userops->ijacobian) { /* system was written as Xdot = F(t,X) */ 436 ierr = MatZeroEntries(*A);CHKERRQ(ierr); 437 ierr = MatShift(*A,shift);CHKERRQ(ierr); 438 if (*A != *B) { 439 ierr = MatZeroEntries(*B);CHKERRQ(ierr); 440 ierr = MatShift(*B,shift);CHKERRQ(ierr); 441 } 442 *flg = SAME_PRECONDITIONER; 443 } 444 } else { 445 if (!ts->userops->ijacobian) { 446 ierr = TSComputeRHSJacobian(ts,t,X,A,B,flg);CHKERRQ(ierr); 447 ierr = MatScale(*A,-1);CHKERRQ(ierr); 448 ierr = MatShift(*A,shift);CHKERRQ(ierr); 449 if (*A != *B) { 450 ierr = MatScale(*B,-1);CHKERRQ(ierr); 451 ierr = MatShift(*B,shift);CHKERRQ(ierr); 452 } 453 } else if (ts->userops->rhsjacobian) { 454 Mat Arhs,Brhs; 455 MatStructure axpy,flg2 = DIFFERENT_NONZERO_PATTERN; 456 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 457 ierr = TSComputeRHSJacobian(ts,t,X,&Arhs,&Brhs,&flg2);CHKERRQ(ierr); 458 axpy = (*flg == flg2) ? SAME_NONZERO_PATTERN : DIFFERENT_NONZERO_PATTERN; 459 ierr = MatAXPY(*A,-1,Arhs,axpy);CHKERRQ(ierr); 460 if (*A != *B) { 461 ierr = MatAXPY(*B,-1,Brhs,axpy);CHKERRQ(ierr); 462 } 463 *flg = PetscMin(*flg,flg2); 464 } 465 } 466 467 ts->ijacobian.time = t; 468 ts->ijacobian.X = X; 469 ts->ijacobian.Xdot = Xdot; 470 ierr = PetscObjectStateQuery((PetscObject)X,&ts->ijacobian.Xstate);CHKERRQ(ierr); 471 ierr = PetscObjectStateQuery((PetscObject)Xdot,&ts->ijacobian.Xdotstate);CHKERRQ(ierr); 472 ts->ijacobian.shift = shift; 473 ts->ijacobian.imex = imex; 474 ts->ijacobian.mstructure = *flg; 475 ierr = PetscLogEventEnd(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr); 476 PetscFunctionReturn(0); 477 } 478 479 #undef __FUNCT__ 480 #define __FUNCT__ "TSSetRHSFunction" 481 /*@C 482 TSSetRHSFunction - Sets the routine for evaluating the function, 483 F(t,u), where U_t = F(t,u). 484 485 Logically Collective on TS 486 487 Input Parameters: 488 + ts - the TS context obtained from TSCreate() 489 . r - vector to put the computed right hand side (or PETSC_NULL to have it created) 490 . f - routine for evaluating the right-hand-side function 491 - ctx - [optional] user-defined context for private data for the 492 function evaluation routine (may be PETSC_NULL) 493 494 Calling sequence of func: 495 $ func (TS ts,PetscReal t,Vec u,Vec F,void *ctx); 496 497 + t - current timestep 498 . u - input vector 499 . F - function vector 500 - ctx - [optional] user-defined function context 501 502 Important: 503 The user MUST call either this routine or TSSetMatrices(). 504 505 Level: beginner 506 507 .keywords: TS, timestep, set, right-hand-side, function 508 509 .seealso: TSSetMatrices() 510 @*/ 511 PetscErrorCode TSSetRHSFunction(TS ts,Vec r,PetscErrorCode (*f)(TS,PetscReal,Vec,Vec,void*),void *ctx) 512 { 513 PetscErrorCode ierr; 514 SNES snes; 515 516 PetscFunctionBegin; 517 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 518 if (r) PetscValidHeaderSpecific(r,VEC_CLASSID,2); 519 if (f) ts->userops->rhsfunction = f; 520 if (ctx) ts->funP = ctx; 521 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 522 ierr = SNESSetFunction(snes,r,SNESTSFormFunction,ts);CHKERRQ(ierr); 523 PetscFunctionReturn(0); 524 } 525 526 #undef __FUNCT__ 527 #define __FUNCT__ "TSSetRHSJacobian" 528 /*@C 529 TSSetRHSJacobian - Sets the function to compute the Jacobian of F, 530 where U_t = F(U,t), as well as the location to store the matrix. 531 Use TSSetMatrices() for linear problems. 532 533 Logically Collective on TS 534 535 Input Parameters: 536 + ts - the TS context obtained from TSCreate() 537 . A - Jacobian matrix 538 . B - preconditioner matrix (usually same as A) 539 . f - the Jacobian evaluation routine 540 - ctx - [optional] user-defined context for private data for the 541 Jacobian evaluation routine (may be PETSC_NULL) 542 543 Calling sequence of func: 544 $ func (TS ts,PetscReal t,Vec u,Mat *A,Mat *B,MatStructure *flag,void *ctx); 545 546 + t - current timestep 547 . u - input vector 548 . A - matrix A, where U_t = A(t)u 549 . B - preconditioner matrix, usually the same as A 550 . flag - flag indicating information about the preconditioner matrix 551 structure (same as flag in KSPSetOperators()) 552 - ctx - [optional] user-defined context for matrix evaluation routine 553 554 Notes: 555 See KSPSetOperators() for important information about setting the flag 556 output parameter in the routine func(). Be sure to read this information! 557 558 The routine func() takes Mat * as the matrix arguments rather than Mat. 559 This allows the matrix evaluation routine to replace A and/or B with a 560 completely new matrix structure (not just different matrix elements) 561 when appropriate, for instance, if the nonzero structure is changing 562 throughout the global iterations. 563 564 Level: beginner 565 566 .keywords: TS, timestep, set, right-hand-side, Jacobian 567 568 .seealso: TSDefaultComputeJacobianColor(), 569 SNESDefaultComputeJacobianColor(), TSSetRHSFunction(), TSSetMatrices() 570 571 @*/ 572 PetscErrorCode TSSetRHSJacobian(TS ts,Mat A,Mat B,TSRHSJacobian f,void *ctx) 573 { 574 PetscErrorCode ierr; 575 SNES snes; 576 577 PetscFunctionBegin; 578 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 579 if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 580 if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 581 if (A) PetscCheckSameComm(ts,1,A,2); 582 if (B) PetscCheckSameComm(ts,1,B,3); 583 584 if (f) ts->userops->rhsjacobian = f; 585 if (ctx) ts->jacP = ctx; 586 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 587 if (!ts->userops->ijacobian) { 588 ierr = SNESSetJacobian(snes,A,B,SNESTSFormJacobian,ts);CHKERRQ(ierr); 589 } 590 if (A) { 591 ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 592 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 593 ts->Arhs = A; 594 } 595 if (B) { 596 ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 597 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 598 ts->Brhs = B; 599 } 600 PetscFunctionReturn(0); 601 } 602 603 604 #undef __FUNCT__ 605 #define __FUNCT__ "TSSetIFunction" 606 /*@C 607 TSSetIFunction - Set the function to compute F(t,U,U_t) where F = 0 is the DAE to be solved. 608 609 Logically Collective on TS 610 611 Input Parameters: 612 + ts - the TS context obtained from TSCreate() 613 . r - vector to hold the residual (or PETSC_NULL to have it created internally) 614 . f - the function evaluation routine 615 - ctx - user-defined context for private data for the function evaluation routine (may be PETSC_NULL) 616 617 Calling sequence of f: 618 $ f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx); 619 620 + t - time at step/stage being solved 621 . u - state vector 622 . u_t - time derivative of state vector 623 . F - function vector 624 - ctx - [optional] user-defined context for matrix evaluation routine 625 626 Important: 627 The user MUST call either this routine, TSSetRHSFunction(), or TSSetMatrices(). This routine must be used when not solving an ODE. 628 629 Level: beginner 630 631 .keywords: TS, timestep, set, DAE, Jacobian 632 633 .seealso: TSSetMatrices(), TSSetRHSFunction(), TSSetIJacobian() 634 @*/ 635 PetscErrorCode TSSetIFunction(TS ts,Vec res,TSIFunction f,void *ctx) 636 { 637 PetscErrorCode ierr; 638 SNES snes; 639 640 PetscFunctionBegin; 641 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 642 if (res) PetscValidHeaderSpecific(res,VEC_CLASSID,2); 643 if (f) ts->userops->ifunction = f; 644 if (ctx) ts->funP = ctx; 645 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 646 ierr = SNESSetFunction(snes,res,SNESTSFormFunction,ts);CHKERRQ(ierr); 647 PetscFunctionReturn(0); 648 } 649 650 #undef __FUNCT__ 651 #define __FUNCT__ "TSGetIFunction" 652 /*@C 653 TSGetIFunction - Returns the vector where the implicit residual is stored and the function/contex to compute it. 654 655 Not Collective 656 657 Input Parameter: 658 . ts - the TS context 659 660 Output Parameter: 661 + r - vector to hold residual (or PETSC_NULL) 662 . func - the function to compute residual (or PETSC_NULL) 663 - ctx - the function context (or PETSC_NULL) 664 665 Level: advanced 666 667 .keywords: TS, nonlinear, get, function 668 669 .seealso: TSSetIFunction(), SNESGetFunction() 670 @*/ 671 PetscErrorCode TSGetIFunction(TS ts,Vec *r,TSIFunction *func,void **ctx) 672 { 673 PetscErrorCode ierr; 674 SNES snes; 675 676 PetscFunctionBegin; 677 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 678 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 679 ierr = SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 680 if (func) *func = ts->userops->ifunction; 681 if (ctx) *ctx = ts->funP; 682 PetscFunctionReturn(0); 683 } 684 685 #undef __FUNCT__ 686 #define __FUNCT__ "TSGetRHSFunction" 687 /*@C 688 TSGetRHSFunction - Returns the vector where the right hand side is stored and the function/context to compute it. 689 690 Not Collective 691 692 Input Parameter: 693 . ts - the TS context 694 695 Output Parameter: 696 + r - vector to hold computed right hand side (or PETSC_NULL) 697 . func - the function to compute right hand side (or PETSC_NULL) 698 - ctx - the function context (or PETSC_NULL) 699 700 Level: advanced 701 702 .keywords: TS, nonlinear, get, function 703 704 .seealso: TSSetRhsfunction(), SNESGetFunction() 705 @*/ 706 PetscErrorCode TSGetRHSFunction(TS ts,Vec *r,TSRHSFunction *func,void **ctx) 707 { 708 PetscErrorCode ierr; 709 SNES snes; 710 711 PetscFunctionBegin; 712 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 713 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 714 ierr = SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 715 if (func) *func = ts->userops->rhsfunction; 716 if (ctx) *ctx = ts->funP; 717 PetscFunctionReturn(0); 718 } 719 720 #undef __FUNCT__ 721 #define __FUNCT__ "TSSetIJacobian" 722 /*@C 723 TSSetIJacobian - Set the function to compute the matrix dF/dU + a*dF/dU_t where F(t,U,U_t) is the function 724 you provided with TSSetIFunction(). 725 726 Logically Collective on TS 727 728 Input Parameters: 729 + ts - the TS context obtained from TSCreate() 730 . A - Jacobian matrix 731 . B - preconditioning matrix for A (may be same as A) 732 . f - the Jacobian evaluation routine 733 - ctx - user-defined context for private data for the Jacobian evaluation routine (may be PETSC_NULL) 734 735 Calling sequence of f: 736 $ f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat *A,Mat *B,MatStructure *flag,void *ctx); 737 738 + t - time at step/stage being solved 739 . U - state vector 740 . U_t - time derivative of state vector 741 . a - shift 742 . A - Jacobian of G(U) = F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t 743 . B - preconditioning matrix for A, may be same as A 744 . flag - flag indicating information about the preconditioner matrix 745 structure (same as flag in KSPSetOperators()) 746 - ctx - [optional] user-defined context for matrix evaluation routine 747 748 Notes: 749 The matrices A and B are exactly the matrices that are used by SNES for the nonlinear solve. 750 751 The matrix dF/dU + a*dF/dU_t you provide turns out to be 752 the Jacobian of G(U) = F(t,U,W+a*U) where F(t,U,U_t) = 0 is the DAE to be solved. 753 The time integrator internally approximates U_t by W+a*U where the positive "shift" 754 a and vector W depend on the integration method, step size, and past states. For example with 755 the backward Euler method a = 1/dt and W = -a*U(previous timestep) so 756 W + a*U = a*(U - U(previous timestep)) = (U - U(previous timestep))/dt 757 758 Level: beginner 759 760 .keywords: TS, timestep, DAE, Jacobian 761 762 .seealso: TSSetIFunction(), TSSetRHSJacobian() 763 764 @*/ 765 PetscErrorCode TSSetIJacobian(TS ts,Mat A,Mat B,TSIJacobian f,void *ctx) 766 { 767 PetscErrorCode ierr; 768 SNES snes; 769 770 PetscFunctionBegin; 771 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 772 if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 773 if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 774 if (A) PetscCheckSameComm(ts,1,A,2); 775 if (B) PetscCheckSameComm(ts,1,B,3); 776 if (f) ts->userops->ijacobian = f; 777 if (ctx) ts->jacP = ctx; 778 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 779 ierr = SNESSetJacobian(snes,A,B,SNESTSFormJacobian,ts);CHKERRQ(ierr); 780 PetscFunctionReturn(0); 781 } 782 783 #undef __FUNCT__ 784 #define __FUNCT__ "TSView" 785 /*@C 786 TSView - Prints the TS data structure. 787 788 Collective on TS 789 790 Input Parameters: 791 + ts - the TS context obtained from TSCreate() 792 - viewer - visualization context 793 794 Options Database Key: 795 . -ts_view - calls TSView() at end of TSStep() 796 797 Notes: 798 The available visualization contexts include 799 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 800 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 801 output where only the first processor opens 802 the file. All other processors send their 803 data to the first processor to print. 804 805 The user can open an alternative visualization context with 806 PetscViewerASCIIOpen() - output to a specified file. 807 808 Level: beginner 809 810 .keywords: TS, timestep, view 811 812 .seealso: PetscViewerASCIIOpen() 813 @*/ 814 PetscErrorCode TSView(TS ts,PetscViewer viewer) 815 { 816 PetscErrorCode ierr; 817 const TSType type; 818 PetscBool iascii,isstring,isundials; 819 820 PetscFunctionBegin; 821 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 822 if (!viewer) { 823 ierr = PetscViewerASCIIGetStdout(((PetscObject)ts)->comm,&viewer);CHKERRQ(ierr); 824 } 825 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 826 PetscCheckSameComm(ts,1,viewer,2); 827 828 ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 829 ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 830 if (iascii) { 831 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ts,viewer,"TS Object");CHKERRQ(ierr); 832 ierr = PetscViewerASCIIPrintf(viewer," maximum steps=%D\n",ts->max_steps);CHKERRQ(ierr); 833 ierr = PetscViewerASCIIPrintf(viewer," maximum time=%G\n",ts->max_time);CHKERRQ(ierr); 834 if (ts->problem_type == TS_NONLINEAR) { 835 ierr = PetscViewerASCIIPrintf(viewer," total number of nonlinear solver iterations=%D\n",ts->nonlinear_its);CHKERRQ(ierr); 836 ierr = PetscViewerASCIIPrintf(viewer," total number of nonlinear solve failures=%D\n",ts->num_snes_failures);CHKERRQ(ierr); 837 } 838 ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",ts->linear_its);CHKERRQ(ierr); 839 ierr = PetscViewerASCIIPrintf(viewer," total number of rejected steps=%D\n",ts->reject);CHKERRQ(ierr); 840 if (ts->ops->view) { 841 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 842 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 843 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 844 } 845 } else if (isstring) { 846 ierr = TSGetType(ts,&type);CHKERRQ(ierr); 847 ierr = PetscViewerStringSPrintf(viewer," %-7.7s",type);CHKERRQ(ierr); 848 } 849 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 850 ierr = PetscTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials);CHKERRQ(ierr); 851 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 852 PetscFunctionReturn(0); 853 } 854 855 856 #undef __FUNCT__ 857 #define __FUNCT__ "TSSetApplicationContext" 858 /*@ 859 TSSetApplicationContext - Sets an optional user-defined context for 860 the timesteppers. 861 862 Logically Collective on TS 863 864 Input Parameters: 865 + ts - the TS context obtained from TSCreate() 866 - usrP - optional user context 867 868 Level: intermediate 869 870 .keywords: TS, timestep, set, application, context 871 872 .seealso: TSGetApplicationContext() 873 @*/ 874 PetscErrorCode TSSetApplicationContext(TS ts,void *usrP) 875 { 876 PetscFunctionBegin; 877 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 878 ts->user = usrP; 879 PetscFunctionReturn(0); 880 } 881 882 #undef __FUNCT__ 883 #define __FUNCT__ "TSGetApplicationContext" 884 /*@ 885 TSGetApplicationContext - Gets the user-defined context for the 886 timestepper. 887 888 Not Collective 889 890 Input Parameter: 891 . ts - the TS context obtained from TSCreate() 892 893 Output Parameter: 894 . usrP - user context 895 896 Level: intermediate 897 898 .keywords: TS, timestep, get, application, context 899 900 .seealso: TSSetApplicationContext() 901 @*/ 902 PetscErrorCode TSGetApplicationContext(TS ts,void *usrP) 903 { 904 PetscFunctionBegin; 905 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 906 *(void**)usrP = ts->user; 907 PetscFunctionReturn(0); 908 } 909 910 #undef __FUNCT__ 911 #define __FUNCT__ "TSGetTimeStepNumber" 912 /*@ 913 TSGetTimeStepNumber - Gets the current number of timesteps. 914 915 Not Collective 916 917 Input Parameter: 918 . ts - the TS context obtained from TSCreate() 919 920 Output Parameter: 921 . iter - number steps so far 922 923 Level: intermediate 924 925 .keywords: TS, timestep, get, iteration, number 926 @*/ 927 PetscErrorCode TSGetTimeStepNumber(TS ts,PetscInt* iter) 928 { 929 PetscFunctionBegin; 930 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 931 PetscValidIntPointer(iter,2); 932 *iter = ts->steps; 933 PetscFunctionReturn(0); 934 } 935 936 #undef __FUNCT__ 937 #define __FUNCT__ "TSSetInitialTimeStep" 938 /*@ 939 TSSetInitialTimeStep - Sets the initial timestep to be used, 940 as well as the initial time. 941 942 Logically Collective on TS 943 944 Input Parameters: 945 + ts - the TS context obtained from TSCreate() 946 . initial_time - the initial time 947 - time_step - the size of the timestep 948 949 Level: intermediate 950 951 .seealso: TSSetTimeStep(), TSGetTimeStep() 952 953 .keywords: TS, set, initial, timestep 954 @*/ 955 PetscErrorCode TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step) 956 { 957 PetscErrorCode ierr; 958 959 PetscFunctionBegin; 960 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 961 ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr); 962 ts->initial_time_step = time_step; 963 ts->ptime = initial_time; 964 PetscFunctionReturn(0); 965 } 966 967 #undef __FUNCT__ 968 #define __FUNCT__ "TSSetTimeStep" 969 /*@ 970 TSSetTimeStep - Allows one to reset the timestep at any time, 971 useful for simple pseudo-timestepping codes. 972 973 Logically Collective on TS 974 975 Input Parameters: 976 + ts - the TS context obtained from TSCreate() 977 - time_step - the size of the timestep 978 979 Level: intermediate 980 981 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 982 983 .keywords: TS, set, timestep 984 @*/ 985 PetscErrorCode TSSetTimeStep(TS ts,PetscReal time_step) 986 { 987 PetscFunctionBegin; 988 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 989 PetscValidLogicalCollectiveReal(ts,time_step,2); 990 ts->time_step = time_step; 991 ts->next_time_step = time_step; 992 PetscFunctionReturn(0); 993 } 994 995 #undef __FUNCT__ 996 #define __FUNCT__ "TSSetExactFinalTime" 997 /*@ 998 TSSetExactFinalTime - Determines whether to interpolate solution to the 999 exact final time requested by the user or just returns it at the final time 1000 it computed. 1001 1002 Logically Collective on TS 1003 1004 Input Parameter: 1005 + ts - the time-step context 1006 - ft - PETSC_TRUE if interpolates, else PETSC_FALSE 1007 1008 Level: beginner 1009 1010 .seealso: TSSetDuration() 1011 @*/ 1012 PetscErrorCode TSSetExactFinalTime(TS ts,PetscBool flg) 1013 { 1014 1015 PetscFunctionBegin; 1016 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1017 ts->exact_final_time = flg; 1018 PetscFunctionReturn(0); 1019 } 1020 1021 #undef __FUNCT__ 1022 #define __FUNCT__ "TSGetTimeStep" 1023 /*@ 1024 TSGetTimeStep - Gets the current timestep size. 1025 1026 Not Collective 1027 1028 Input Parameter: 1029 . ts - the TS context obtained from TSCreate() 1030 1031 Output Parameter: 1032 . dt - the current timestep size 1033 1034 Level: intermediate 1035 1036 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 1037 1038 .keywords: TS, get, timestep 1039 @*/ 1040 PetscErrorCode TSGetTimeStep(TS ts,PetscReal* dt) 1041 { 1042 PetscFunctionBegin; 1043 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1044 PetscValidDoublePointer(dt,2); 1045 *dt = ts->time_step; 1046 PetscFunctionReturn(0); 1047 } 1048 1049 #undef __FUNCT__ 1050 #define __FUNCT__ "TSGetSolution" 1051 /*@ 1052 TSGetSolution - Returns the solution at the present timestep. It 1053 is valid to call this routine inside the function that you are evaluating 1054 in order to move to the new timestep. This vector not changed until 1055 the solution at the next timestep has been calculated. 1056 1057 Not Collective, but Vec returned is parallel if TS is parallel 1058 1059 Input Parameter: 1060 . ts - the TS context obtained from TSCreate() 1061 1062 Output Parameter: 1063 . v - the vector containing the solution 1064 1065 Level: intermediate 1066 1067 .seealso: TSGetTimeStep() 1068 1069 .keywords: TS, timestep, get, solution 1070 @*/ 1071 PetscErrorCode TSGetSolution(TS ts,Vec *v) 1072 { 1073 PetscFunctionBegin; 1074 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1075 PetscValidPointer(v,2); 1076 *v = ts->vec_sol; 1077 PetscFunctionReturn(0); 1078 } 1079 1080 /* ----- Routines to initialize and destroy a timestepper ---- */ 1081 #undef __FUNCT__ 1082 #define __FUNCT__ "TSSetProblemType" 1083 /*@ 1084 TSSetProblemType - Sets the type of problem to be solved. 1085 1086 Not collective 1087 1088 Input Parameters: 1089 + ts - The TS 1090 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 1091 .vb 1092 U_t = A U 1093 U_t = A(t) U 1094 U_t = F(t,U) 1095 .ve 1096 1097 Level: beginner 1098 1099 .keywords: TS, problem type 1100 .seealso: TSSetUp(), TSProblemType, TS 1101 @*/ 1102 PetscErrorCode TSSetProblemType(TS ts, TSProblemType type) 1103 { 1104 PetscErrorCode ierr; 1105 1106 PetscFunctionBegin; 1107 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1108 ts->problem_type = type; 1109 if (type == TS_LINEAR) { 1110 SNES snes; 1111 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1112 ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr); 1113 } 1114 PetscFunctionReturn(0); 1115 } 1116 1117 #undef __FUNCT__ 1118 #define __FUNCT__ "TSGetProblemType" 1119 /*@C 1120 TSGetProblemType - Gets the type of problem to be solved. 1121 1122 Not collective 1123 1124 Input Parameter: 1125 . ts - The TS 1126 1127 Output Parameter: 1128 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 1129 .vb 1130 M U_t = A U 1131 M(t) U_t = A(t) U 1132 U_t = F(t,U) 1133 .ve 1134 1135 Level: beginner 1136 1137 .keywords: TS, problem type 1138 .seealso: TSSetUp(), TSProblemType, TS 1139 @*/ 1140 PetscErrorCode TSGetProblemType(TS ts, TSProblemType *type) 1141 { 1142 PetscFunctionBegin; 1143 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1144 PetscValidIntPointer(type,2); 1145 *type = ts->problem_type; 1146 PetscFunctionReturn(0); 1147 } 1148 1149 #undef __FUNCT__ 1150 #define __FUNCT__ "TSSetUp" 1151 /*@ 1152 TSSetUp - Sets up the internal data structures for the later use 1153 of a timestepper. 1154 1155 Collective on TS 1156 1157 Input Parameter: 1158 . ts - the TS context obtained from TSCreate() 1159 1160 Notes: 1161 For basic use of the TS solvers the user need not explicitly call 1162 TSSetUp(), since these actions will automatically occur during 1163 the call to TSStep(). However, if one wishes to control this 1164 phase separately, TSSetUp() should be called after TSCreate() 1165 and optional routines of the form TSSetXXX(), but before TSStep(). 1166 1167 Level: advanced 1168 1169 .keywords: TS, timestep, setup 1170 1171 .seealso: TSCreate(), TSStep(), TSDestroy() 1172 @*/ 1173 PetscErrorCode TSSetUp(TS ts) 1174 { 1175 PetscErrorCode ierr; 1176 1177 PetscFunctionBegin; 1178 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1179 if (ts->setupcalled) PetscFunctionReturn(0); 1180 1181 if (!((PetscObject)ts)->type_name) { 1182 ierr = TSSetType(ts,TSEULER);CHKERRQ(ierr); 1183 } 1184 if (ts->exact_final_time == PETSC_DECIDE) ts->exact_final_time = PETSC_FALSE; 1185 1186 if (!ts->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first"); 1187 1188 if (ts->ops->setup) { 1189 ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr); 1190 } 1191 1192 ts->setupcalled = PETSC_TRUE; 1193 PetscFunctionReturn(0); 1194 } 1195 1196 #undef __FUNCT__ 1197 #define __FUNCT__ "TSReset" 1198 /*@ 1199 TSReset - Resets a TS context and removes any allocated Vecs and Mats. 1200 1201 Collective on TS 1202 1203 Input Parameter: 1204 . ts - the TS context obtained from TSCreate() 1205 1206 Level: beginner 1207 1208 .keywords: TS, timestep, reset 1209 1210 .seealso: TSCreate(), TSSetup(), TSDestroy() 1211 @*/ 1212 PetscErrorCode TSReset(TS ts) 1213 { 1214 PetscErrorCode ierr; 1215 1216 PetscFunctionBegin; 1217 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1218 if (ts->ops->reset) { 1219 ierr = (*ts->ops->reset)(ts);CHKERRQ(ierr); 1220 } 1221 if (ts->snes) {ierr = SNESReset(ts->snes);CHKERRQ(ierr);} 1222 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 1223 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 1224 ierr = VecDestroy(&ts->Frhs);CHKERRQ(ierr); 1225 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 1226 ierr = VecDestroyVecs(ts->nwork,&ts->work);CHKERRQ(ierr); 1227 ts->setupcalled = PETSC_FALSE; 1228 PetscFunctionReturn(0); 1229 } 1230 1231 #undef __FUNCT__ 1232 #define __FUNCT__ "TSDestroy" 1233 /*@ 1234 TSDestroy - Destroys the timestepper context that was created 1235 with TSCreate(). 1236 1237 Collective on TS 1238 1239 Input Parameter: 1240 . ts - the TS context obtained from TSCreate() 1241 1242 Level: beginner 1243 1244 .keywords: TS, timestepper, destroy 1245 1246 .seealso: TSCreate(), TSSetUp(), TSSolve() 1247 @*/ 1248 PetscErrorCode TSDestroy(TS *ts) 1249 { 1250 PetscErrorCode ierr; 1251 1252 PetscFunctionBegin; 1253 if (!*ts) PetscFunctionReturn(0); 1254 PetscValidHeaderSpecific((*ts),TS_CLASSID,1); 1255 if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; PetscFunctionReturn(0);} 1256 1257 ierr = TSReset((*ts));CHKERRQ(ierr); 1258 1259 /* if memory was published with AMS then destroy it */ 1260 ierr = PetscObjectDepublish((*ts));CHKERRQ(ierr); 1261 if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);} 1262 1263 ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr); 1264 ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr); 1265 ierr = TSMonitorCancel((*ts));CHKERRQ(ierr); 1266 1267 ierr = PetscFree((*ts)->userops); 1268 1269 ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr); 1270 PetscFunctionReturn(0); 1271 } 1272 1273 #undef __FUNCT__ 1274 #define __FUNCT__ "TSGetSNES" 1275 /*@ 1276 TSGetSNES - Returns the SNES (nonlinear solver) associated with 1277 a TS (timestepper) context. Valid only for nonlinear problems. 1278 1279 Not Collective, but SNES is parallel if TS is parallel 1280 1281 Input Parameter: 1282 . ts - the TS context obtained from TSCreate() 1283 1284 Output Parameter: 1285 . snes - the nonlinear solver context 1286 1287 Notes: 1288 The user can then directly manipulate the SNES context to set various 1289 options, etc. Likewise, the user can then extract and manipulate the 1290 KSP, KSP, and PC contexts as well. 1291 1292 TSGetSNES() does not work for integrators that do not use SNES; in 1293 this case TSGetSNES() returns PETSC_NULL in snes. 1294 1295 Level: beginner 1296 1297 .keywords: timestep, get, SNES 1298 @*/ 1299 PetscErrorCode TSGetSNES(TS ts,SNES *snes) 1300 { 1301 PetscErrorCode ierr; 1302 1303 PetscFunctionBegin; 1304 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1305 PetscValidPointer(snes,2); 1306 if (!ts->snes) { 1307 ierr = SNESCreate(((PetscObject)ts)->comm,&ts->snes);CHKERRQ(ierr); 1308 ierr = PetscLogObjectParent(ts,ts->snes);CHKERRQ(ierr); 1309 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr); 1310 if (ts->problem_type == TS_LINEAR) { 1311 ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr); 1312 } 1313 } 1314 *snes = ts->snes; 1315 PetscFunctionReturn(0); 1316 } 1317 1318 #undef __FUNCT__ 1319 #define __FUNCT__ "TSGetKSP" 1320 /*@ 1321 TSGetKSP - Returns the KSP (linear solver) associated with 1322 a TS (timestepper) context. 1323 1324 Not Collective, but KSP is parallel if TS is parallel 1325 1326 Input Parameter: 1327 . ts - the TS context obtained from TSCreate() 1328 1329 Output Parameter: 1330 . ksp - the nonlinear solver context 1331 1332 Notes: 1333 The user can then directly manipulate the KSP context to set various 1334 options, etc. Likewise, the user can then extract and manipulate the 1335 KSP and PC contexts as well. 1336 1337 TSGetKSP() does not work for integrators that do not use KSP; 1338 in this case TSGetKSP() returns PETSC_NULL in ksp. 1339 1340 Level: beginner 1341 1342 .keywords: timestep, get, KSP 1343 @*/ 1344 PetscErrorCode TSGetKSP(TS ts,KSP *ksp) 1345 { 1346 PetscErrorCode ierr; 1347 SNES snes; 1348 1349 PetscFunctionBegin; 1350 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1351 PetscValidPointer(ksp,2); 1352 if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first"); 1353 if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()"); 1354 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1355 ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr); 1356 PetscFunctionReturn(0); 1357 } 1358 1359 /* ----------- Routines to set solver parameters ---------- */ 1360 1361 #undef __FUNCT__ 1362 #define __FUNCT__ "TSGetDuration" 1363 /*@ 1364 TSGetDuration - Gets the maximum number of timesteps to use and 1365 maximum time for iteration. 1366 1367 Not Collective 1368 1369 Input Parameters: 1370 + ts - the TS context obtained from TSCreate() 1371 . maxsteps - maximum number of iterations to use, or PETSC_NULL 1372 - maxtime - final time to iterate to, or PETSC_NULL 1373 1374 Level: intermediate 1375 1376 .keywords: TS, timestep, get, maximum, iterations, time 1377 @*/ 1378 PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime) 1379 { 1380 PetscFunctionBegin; 1381 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1382 if (maxsteps) { 1383 PetscValidIntPointer(maxsteps,2); 1384 *maxsteps = ts->max_steps; 1385 } 1386 if (maxtime ) { 1387 PetscValidScalarPointer(maxtime,3); 1388 *maxtime = ts->max_time; 1389 } 1390 PetscFunctionReturn(0); 1391 } 1392 1393 #undef __FUNCT__ 1394 #define __FUNCT__ "TSSetDuration" 1395 /*@ 1396 TSSetDuration - Sets the maximum number of timesteps to use and 1397 maximum time for iteration. 1398 1399 Logically Collective on TS 1400 1401 Input Parameters: 1402 + ts - the TS context obtained from TSCreate() 1403 . maxsteps - maximum number of iterations to use 1404 - maxtime - final time to iterate to 1405 1406 Options Database Keys: 1407 . -ts_max_steps <maxsteps> - Sets maxsteps 1408 . -ts_max_time <maxtime> - Sets maxtime 1409 1410 Notes: 1411 The default maximum number of iterations is 5000. Default time is 5.0 1412 1413 Level: intermediate 1414 1415 .keywords: TS, timestep, set, maximum, iterations 1416 1417 .seealso: TSSetExactFinalTime() 1418 @*/ 1419 PetscErrorCode TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime) 1420 { 1421 PetscFunctionBegin; 1422 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1423 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 1424 PetscValidLogicalCollectiveReal(ts,maxtime,2); 1425 if (maxsteps >= 0) ts->max_steps = maxsteps; 1426 if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime; 1427 PetscFunctionReturn(0); 1428 } 1429 1430 #undef __FUNCT__ 1431 #define __FUNCT__ "TSSetSolution" 1432 /*@ 1433 TSSetSolution - Sets the initial solution vector 1434 for use by the TS routines. 1435 1436 Logically Collective on TS and Vec 1437 1438 Input Parameters: 1439 + ts - the TS context obtained from TSCreate() 1440 - x - the solution vector 1441 1442 Level: beginner 1443 1444 .keywords: TS, timestep, set, solution, initial conditions 1445 @*/ 1446 PetscErrorCode TSSetSolution(TS ts,Vec x) 1447 { 1448 PetscErrorCode ierr; 1449 1450 PetscFunctionBegin; 1451 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1452 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1453 ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 1454 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 1455 ts->vec_sol = x; 1456 PetscFunctionReturn(0); 1457 } 1458 1459 #undef __FUNCT__ 1460 #define __FUNCT__ "TSSetPreStep" 1461 /*@C 1462 TSSetPreStep - Sets the general-purpose function 1463 called once at the beginning of each time step. 1464 1465 Logically Collective on TS 1466 1467 Input Parameters: 1468 + ts - The TS context obtained from TSCreate() 1469 - func - The function 1470 1471 Calling sequence of func: 1472 . func (TS ts); 1473 1474 Level: intermediate 1475 1476 .keywords: TS, timestep 1477 @*/ 1478 PetscErrorCode TSSetPreStep(TS ts, PetscErrorCode (*func)(TS)) 1479 { 1480 PetscFunctionBegin; 1481 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1482 ts->ops->prestep = func; 1483 PetscFunctionReturn(0); 1484 } 1485 1486 #undef __FUNCT__ 1487 #define __FUNCT__ "TSPreStep" 1488 /*@C 1489 TSPreStep - Runs the user-defined pre-step function. 1490 1491 Collective on TS 1492 1493 Input Parameters: 1494 . ts - The TS context obtained from TSCreate() 1495 1496 Notes: 1497 TSPreStep() is typically used within time stepping implementations, 1498 so most users would not generally call this routine themselves. 1499 1500 Level: developer 1501 1502 .keywords: TS, timestep 1503 @*/ 1504 PetscErrorCode TSPreStep(TS ts) 1505 { 1506 PetscErrorCode ierr; 1507 1508 PetscFunctionBegin; 1509 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1510 if (ts->ops->prestep) { 1511 PetscStackPush("TS PreStep function"); 1512 ierr = (*ts->ops->prestep)(ts);CHKERRQ(ierr); 1513 PetscStackPop; 1514 } 1515 PetscFunctionReturn(0); 1516 } 1517 1518 #undef __FUNCT__ 1519 #define __FUNCT__ "TSSetPostStep" 1520 /*@C 1521 TSSetPostStep - Sets the general-purpose function 1522 called once at the end of each time step. 1523 1524 Logically Collective on TS 1525 1526 Input Parameters: 1527 + ts - The TS context obtained from TSCreate() 1528 - func - The function 1529 1530 Calling sequence of func: 1531 . func (TS ts); 1532 1533 Level: intermediate 1534 1535 .keywords: TS, timestep 1536 @*/ 1537 PetscErrorCode TSSetPostStep(TS ts, PetscErrorCode (*func)(TS)) 1538 { 1539 PetscFunctionBegin; 1540 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1541 ts->ops->poststep = func; 1542 PetscFunctionReturn(0); 1543 } 1544 1545 #undef __FUNCT__ 1546 #define __FUNCT__ "TSPostStep" 1547 /*@C 1548 TSPostStep - Runs the user-defined post-step function. 1549 1550 Collective on TS 1551 1552 Input Parameters: 1553 . ts - The TS context obtained from TSCreate() 1554 1555 Notes: 1556 TSPostStep() is typically used within time stepping implementations, 1557 so most users would not generally call this routine themselves. 1558 1559 Level: developer 1560 1561 .keywords: TS, timestep 1562 @*/ 1563 PetscErrorCode TSPostStep(TS ts) 1564 { 1565 PetscErrorCode ierr; 1566 1567 PetscFunctionBegin; 1568 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1569 if (ts->ops->poststep) { 1570 PetscStackPush("TS PostStep function"); 1571 ierr = (*ts->ops->poststep)(ts);CHKERRQ(ierr); 1572 PetscStackPop; 1573 } 1574 PetscFunctionReturn(0); 1575 } 1576 1577 /* ------------ Routines to set performance monitoring options ----------- */ 1578 1579 #undef __FUNCT__ 1580 #define __FUNCT__ "TSMonitorSet" 1581 /*@C 1582 TSMonitorSet - Sets an ADDITIONAL function that is to be used at every 1583 timestep to display the iteration's progress. 1584 1585 Logically Collective on TS 1586 1587 Input Parameters: 1588 + ts - the TS context obtained from TSCreate() 1589 . monitor - monitoring routine 1590 . mctx - [optional] user-defined context for private data for the 1591 monitor routine (use PETSC_NULL if no context is desired) 1592 - monitordestroy - [optional] routine that frees monitor context 1593 (may be PETSC_NULL) 1594 1595 Calling sequence of monitor: 1596 $ int monitor(TS ts,PetscInt steps,PetscReal time,Vec x,void *mctx) 1597 1598 + ts - the TS context 1599 . steps - iteration number 1600 . time - current time 1601 . x - current iterate 1602 - mctx - [optional] monitoring context 1603 1604 Notes: 1605 This routine adds an additional monitor to the list of monitors that 1606 already has been loaded. 1607 1608 Fortran notes: Only a single monitor function can be set for each TS object 1609 1610 Level: intermediate 1611 1612 .keywords: TS, timestep, set, monitor 1613 1614 .seealso: TSMonitorDefault(), TSMonitorCancel() 1615 @*/ 1616 PetscErrorCode TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**)) 1617 { 1618 PetscFunctionBegin; 1619 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1620 if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 1621 ts->monitor[ts->numbermonitors] = monitor; 1622 ts->mdestroy[ts->numbermonitors] = mdestroy; 1623 ts->monitorcontext[ts->numbermonitors++] = (void*)mctx; 1624 PetscFunctionReturn(0); 1625 } 1626 1627 #undef __FUNCT__ 1628 #define __FUNCT__ "TSMonitorCancel" 1629 /*@C 1630 TSMonitorCancel - Clears all the monitors that have been set on a time-step object. 1631 1632 Logically Collective on TS 1633 1634 Input Parameters: 1635 . ts - the TS context obtained from TSCreate() 1636 1637 Notes: 1638 There is no way to remove a single, specific monitor. 1639 1640 Level: intermediate 1641 1642 .keywords: TS, timestep, set, monitor 1643 1644 .seealso: TSMonitorDefault(), TSMonitorSet() 1645 @*/ 1646 PetscErrorCode TSMonitorCancel(TS ts) 1647 { 1648 PetscErrorCode ierr; 1649 PetscInt i; 1650 1651 PetscFunctionBegin; 1652 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1653 for (i=0; i<ts->numbermonitors; i++) { 1654 if (ts->mdestroy[i]) { 1655 ierr = (*ts->mdestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr); 1656 } 1657 } 1658 ts->numbermonitors = 0; 1659 PetscFunctionReturn(0); 1660 } 1661 1662 #undef __FUNCT__ 1663 #define __FUNCT__ "TSMonitorDefault" 1664 /*@ 1665 TSMonitorDefault - Sets the Default monitor 1666 1667 Level: intermediate 1668 1669 .keywords: TS, set, monitor 1670 1671 .seealso: TSMonitorDefault(), TSMonitorSet() 1672 @*/ 1673 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,void *dummy) 1674 { 1675 PetscErrorCode ierr; 1676 PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(((PetscObject)ts)->comm); 1677 1678 PetscFunctionBegin; 1679 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 1680 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %G time %G\n",step,ts->time_step,ptime);CHKERRQ(ierr); 1681 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 1682 PetscFunctionReturn(0); 1683 } 1684 1685 #undef __FUNCT__ 1686 #define __FUNCT__ "TSSetRetainStages" 1687 /*@ 1688 TSSetRetainStages - Request that all stages in the upcoming step be stored so that interpolation will be available. 1689 1690 Logically Collective on TS 1691 1692 Input Argument: 1693 . ts - time stepping context 1694 1695 Output Argument: 1696 . flg - PETSC_TRUE or PETSC_FALSE 1697 1698 Level: intermediate 1699 1700 .keywords: TS, set 1701 1702 .seealso: TSInterpolate(), TSSetPostStep() 1703 @*/ 1704 PetscErrorCode TSSetRetainStages(TS ts,PetscBool flg) 1705 { 1706 1707 PetscFunctionBegin; 1708 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1709 ts->retain_stages = flg; 1710 PetscFunctionReturn(0); 1711 } 1712 1713 #undef __FUNCT__ 1714 #define __FUNCT__ "TSInterpolate" 1715 /*@ 1716 TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval 1717 1718 Collective on TS 1719 1720 Input Argument: 1721 + ts - time stepping context 1722 - t - time to interpolate to 1723 1724 Output Argument: 1725 . X - state at given time 1726 1727 Notes: 1728 The user should call TSSetRetainStages() before taking a step in which interpolation will be requested. 1729 1730 Level: intermediate 1731 1732 Developer Notes: 1733 TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints. 1734 1735 .keywords: TS, set 1736 1737 .seealso: TSSetRetainStages(), TSSetPostStep() 1738 @*/ 1739 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec X) 1740 { 1741 PetscErrorCode ierr; 1742 1743 PetscFunctionBegin; 1744 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1745 if (t < ts->ptime - ts->time_step || ts->ptime < t) SETERRQ3(((PetscObject)ts)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Requested time %G not in last time steps [%G,%G]",t,ts->ptime-ts->time_step,ts->ptime); 1746 if (!ts->ops->interpolate) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name); 1747 ierr = (*ts->ops->interpolate)(ts,t,X);CHKERRQ(ierr); 1748 PetscFunctionReturn(0); 1749 } 1750 1751 #undef __FUNCT__ 1752 #define __FUNCT__ "TSStep" 1753 /*@ 1754 TSStep - Steps one time step 1755 1756 Collective on TS 1757 1758 Input Parameter: 1759 . ts - the TS context obtained from TSCreate() 1760 1761 Level: intermediate 1762 1763 .keywords: TS, timestep, solve 1764 1765 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve() 1766 @*/ 1767 PetscErrorCode TSStep(TS ts) 1768 { 1769 PetscErrorCode ierr; 1770 1771 PetscFunctionBegin; 1772 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1773 1774 ierr = TSSetUp(ts);CHKERRQ(ierr); 1775 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 PetscFunctionReturn(0); 1780 } 1781 1782 #undef __FUNCT__ 1783 #define __FUNCT__ "TSSolve" 1784 /*@ 1785 TSSolve - Steps the requested number of timesteps. 1786 1787 Collective on TS 1788 1789 Input Parameter: 1790 + ts - the TS context obtained from TSCreate() 1791 - x - the solution vector, or PETSC_NULL if it was set with TSSetSolution() 1792 1793 Output Parameter: 1794 . ftime - time of the state vector x upon completion 1795 1796 Level: beginner 1797 1798 Notes: 1799 The final time returned by this function may be different from the time of the internally 1800 held state accessible by TSGetSolution() and TSGetTime() because the method may have 1801 stepped over the final time. 1802 1803 .keywords: TS, timestep, solve 1804 1805 .seealso: TSCreate(), TSSetSolution(), TSStep() 1806 @*/ 1807 PetscErrorCode TSSolve(TS ts,Vec x,PetscReal *ftime) 1808 { 1809 PetscInt i; 1810 PetscBool flg; 1811 char filename[PETSC_MAX_PATH_LEN]; 1812 PetscViewer viewer; 1813 PetscErrorCode ierr; 1814 1815 PetscFunctionBegin; 1816 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1817 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1818 if (ts->exact_final_time) { /* Need ts->vec_sol to be distinct so it is not overwritten when we interpolate at the end */ 1819 if (!ts->vec_sol || x == ts->vec_sol) { 1820 Vec y; 1821 ierr = VecDuplicate(x,&y);CHKERRQ(ierr); 1822 ierr = VecCopy(x,y);CHKERRQ(ierr); 1823 ierr = TSSetSolution(ts,y);CHKERRQ(ierr); 1824 ierr = VecDestroy(&y);CHKERRQ(ierr); /* grant ownership */ 1825 } else { 1826 ierr = VecCopy(x,ts->vec_sol);CHKERRQ(ierr); 1827 } 1828 } else { 1829 ierr = TSSetSolution(ts,x);CHKERRQ(ierr); 1830 } 1831 ierr = TSSetUp(ts);CHKERRQ(ierr); 1832 /* reset time step and iteration counters */ 1833 ts->steps = 0; 1834 ts->linear_its = 0; 1835 ts->nonlinear_its = 0; 1836 ts->num_snes_failures = 0; 1837 ts->reject = 0; 1838 ts->reason = TS_CONVERGED_ITERATING; 1839 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 1840 1841 if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */ 1842 ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr); 1843 ierr = VecCopy(ts->vec_sol,x);CHKERRQ(ierr); 1844 if (ftime) *ftime = ts->ptime; 1845 } else { 1846 i = 0; 1847 if (i >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 1848 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 1849 /* steps the requested number of timesteps. */ 1850 while (!ts->reason) { 1851 ierr = TSPreStep(ts);CHKERRQ(ierr); 1852 ierr = TSStep(ts);CHKERRQ(ierr); 1853 if (ts->reason < 0) { 1854 if (ts->errorifstepfailed) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_NOT_CONVERGED,"TSStep has failed"); 1855 } else if (++i >= ts->max_steps) { 1856 ts->reason = TS_CONVERGED_ITS; 1857 } else if (ts->ptime >= ts->max_time) { 1858 ts->reason = TS_CONVERGED_TIME; 1859 } 1860 ierr = TSPostStep(ts);CHKERRQ(ierr); 1861 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 1862 } 1863 if (ts->exact_final_time && ts->ptime >= ts->max_time) { 1864 ierr = TSInterpolate(ts,ts->max_time,x);CHKERRQ(ierr); 1865 if (ftime) *ftime = ts->max_time; 1866 } else { 1867 if (x != ts->vec_sol) { 1868 ierr = VecCopy(ts->vec_sol,x);CHKERRQ(ierr); 1869 } 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