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