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