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 = PetscOptionsBool("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",opt,&opt,PETSC_NULL);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 = PetscOptionsBool("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",opt,&opt,PETSC_NULL);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->showinitial) { 2697 PetscReal pause; 2698 ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr); 2699 ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr); 2700 ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr); 2701 ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr); 2702 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr); 2703 } 2704 ierr = VecView(x,ictx->viewer);CHKERRQ(ierr); 2705 if (ictx->showinitial) { 2706 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr); 2707 } 2708 PetscFunctionReturn(0); 2709 } 2710 2711 2712 #undef __FUNCT__ 2713 #define __FUNCT__ "TSMonitorDrawCtxDestroy" 2714 /*@C 2715 TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution() 2716 2717 Collective on TS 2718 2719 Input Parameters: 2720 . ctx - the monitor context 2721 2722 Level: intermediate 2723 2724 .keywords: TS, vector, monitor, view 2725 2726 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError() 2727 @*/ 2728 PetscErrorCode TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx) 2729 { 2730 PetscErrorCode ierr; 2731 2732 PetscFunctionBegin; 2733 ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr); 2734 ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr); 2735 ierr = PetscFree(*ictx);CHKERRQ(ierr); 2736 PetscFunctionReturn(0); 2737 } 2738 2739 #undef __FUNCT__ 2740 #define __FUNCT__ "TSMonitorDrawCtxCreate" 2741 /*@C 2742 TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx 2743 2744 Collective on TS 2745 2746 Input Parameter: 2747 . ts - time-step context 2748 2749 Output Patameter: 2750 . ctx - the monitor context 2751 2752 Level: intermediate 2753 2754 .keywords: TS, vector, monitor, view 2755 2756 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx() 2757 @*/ 2758 PetscErrorCode TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx) 2759 { 2760 PetscErrorCode ierr; 2761 2762 PetscFunctionBegin; 2763 ierr = PetscNew(struct _n_TSMonitorDrawCtx,ctx);CHKERRQ(ierr); 2764 ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr); 2765 (*ctx)->showinitial = PETSC_FALSE; 2766 (*ctx)->howoften = howoften; 2767 ierr = PetscOptionsGetBool(PETSC_NULL,"-ts_monitor_solution_initial",&(*ctx)->showinitial,PETSC_NULL);CHKERRQ(ierr); 2768 PetscFunctionReturn(0); 2769 } 2770 2771 #undef __FUNCT__ 2772 #define __FUNCT__ "TSMonitorDrawError" 2773 /*@C 2774 TSMonitorDrawError - Monitors progress of the TS solvers by calling 2775 VecView() for the error at each timestep 2776 2777 Collective on TS 2778 2779 Input Parameters: 2780 + ts - the TS context 2781 . step - current time-step 2782 . ptime - current time 2783 - dummy - either a viewer or PETSC_NULL 2784 2785 Level: intermediate 2786 2787 .keywords: TS, vector, monitor, view 2788 2789 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 2790 @*/ 2791 PetscErrorCode TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec x,void *dummy) 2792 { 2793 PetscErrorCode ierr; 2794 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 2795 PetscViewer viewer = ctx->viewer; 2796 Vec work; 2797 2798 PetscFunctionBegin; 2799 ierr = VecDuplicate(x,&work);CHKERRQ(ierr); 2800 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 2801 ierr = VecAXPY(work,-1.0,x);CHKERRQ(ierr); 2802 ierr = VecView(work,viewer);CHKERRQ(ierr); 2803 ierr = VecDestroy(&work);CHKERRQ(ierr); 2804 PetscFunctionReturn(0); 2805 } 2806 2807 #undef __FUNCT__ 2808 #define __FUNCT__ "TSSetDM" 2809 /*@ 2810 TSSetDM - Sets the DM that may be used by some preconditioners 2811 2812 Logically Collective on TS and DM 2813 2814 Input Parameters: 2815 + ts - the preconditioner context 2816 - dm - the dm 2817 2818 Level: intermediate 2819 2820 2821 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM() 2822 @*/ 2823 PetscErrorCode TSSetDM(TS ts,DM dm) 2824 { 2825 PetscErrorCode ierr; 2826 SNES snes; 2827 TSDM tsdm; 2828 2829 PetscFunctionBegin; 2830 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2831 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 2832 if (ts->dm) { /* Move the TSDM context over to the new DM unless the new DM already has one */ 2833 PetscContainer oldcontainer,container; 2834 ierr = PetscObjectQuery((PetscObject)ts->dm,"TSDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 2835 ierr = PetscObjectQuery((PetscObject)dm,"TSDM",(PetscObject*)&container);CHKERRQ(ierr); 2836 if (oldcontainer && !container) { 2837 ierr = DMTSCopyContext(ts->dm,dm);CHKERRQ(ierr); 2838 ierr = DMTSGetContext(ts->dm,&tsdm);CHKERRQ(ierr); 2839 if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */ 2840 tsdm->originaldm = dm; 2841 } 2842 } 2843 ierr = DMDestroy(&ts->dm);CHKERRQ(ierr); 2844 } 2845 ts->dm = dm; 2846 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2847 ierr = SNESSetDM(snes,dm);CHKERRQ(ierr); 2848 PetscFunctionReturn(0); 2849 } 2850 2851 #undef __FUNCT__ 2852 #define __FUNCT__ "TSGetDM" 2853 /*@ 2854 TSGetDM - Gets the DM that may be used by some preconditioners 2855 2856 Not Collective 2857 2858 Input Parameter: 2859 . ts - the preconditioner context 2860 2861 Output Parameter: 2862 . dm - the dm 2863 2864 Level: intermediate 2865 2866 2867 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM() 2868 @*/ 2869 PetscErrorCode TSGetDM(TS ts,DM *dm) 2870 { 2871 PetscErrorCode ierr; 2872 2873 PetscFunctionBegin; 2874 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2875 if (!ts->dm) { 2876 ierr = DMShellCreate(((PetscObject)ts)->comm,&ts->dm);CHKERRQ(ierr); 2877 if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 2878 } 2879 *dm = ts->dm; 2880 PetscFunctionReturn(0); 2881 } 2882 2883 #undef __FUNCT__ 2884 #define __FUNCT__ "SNESTSFormFunction" 2885 /*@ 2886 SNESTSFormFunction - Function to evaluate nonlinear residual 2887 2888 Logically Collective on SNES 2889 2890 Input Parameter: 2891 + snes - nonlinear solver 2892 . X - the current state at which to evaluate the residual 2893 - ctx - user context, must be a TS 2894 2895 Output Parameter: 2896 . F - the nonlinear residual 2897 2898 Notes: 2899 This function is not normally called by users and is automatically registered with the SNES used by TS. 2900 It is most frequently passed to MatFDColoringSetFunction(). 2901 2902 Level: advanced 2903 2904 .seealso: SNESSetFunction(), MatFDColoringSetFunction() 2905 @*/ 2906 PetscErrorCode SNESTSFormFunction(SNES snes,Vec X,Vec F,void *ctx) 2907 { 2908 TS ts = (TS)ctx; 2909 PetscErrorCode ierr; 2910 2911 PetscFunctionBegin; 2912 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2913 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2914 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 2915 PetscValidHeaderSpecific(ts,TS_CLASSID,4); 2916 ierr = (ts->ops->snesfunction)(snes,X,F,ts);CHKERRQ(ierr); 2917 PetscFunctionReturn(0); 2918 } 2919 2920 #undef __FUNCT__ 2921 #define __FUNCT__ "SNESTSFormJacobian" 2922 /*@ 2923 SNESTSFormJacobian - Function to evaluate the Jacobian 2924 2925 Collective on SNES 2926 2927 Input Parameter: 2928 + snes - nonlinear solver 2929 . X - the current state at which to evaluate the residual 2930 - ctx - user context, must be a TS 2931 2932 Output Parameter: 2933 + A - the Jacobian 2934 . B - the preconditioning matrix (may be the same as A) 2935 - flag - indicates any structure change in the matrix 2936 2937 Notes: 2938 This function is not normally called by users and is automatically registered with the SNES used by TS. 2939 2940 Level: developer 2941 2942 .seealso: SNESSetJacobian() 2943 @*/ 2944 PetscErrorCode SNESTSFormJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flag,void *ctx) 2945 { 2946 TS ts = (TS)ctx; 2947 PetscErrorCode ierr; 2948 2949 PetscFunctionBegin; 2950 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2951 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2952 PetscValidPointer(A,3); 2953 PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 2954 PetscValidPointer(B,4); 2955 PetscValidHeaderSpecific(*B,MAT_CLASSID,4); 2956 PetscValidPointer(flag,5); 2957 PetscValidHeaderSpecific(ts,TS_CLASSID,6); 2958 ierr = (ts->ops->snesjacobian)(snes,X,A,B,flag,ts);CHKERRQ(ierr); 2959 PetscFunctionReturn(0); 2960 } 2961 2962 #undef __FUNCT__ 2963 #define __FUNCT__ "TSComputeRHSFunctionLinear" 2964 /*@C 2965 TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems only 2966 2967 Collective on TS 2968 2969 Input Arguments: 2970 + ts - time stepping context 2971 . t - time at which to evaluate 2972 . X - state at which to evaluate 2973 - ctx - context 2974 2975 Output Arguments: 2976 . F - right hand side 2977 2978 Level: intermediate 2979 2980 Notes: 2981 This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems. 2982 The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian(). 2983 2984 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 2985 @*/ 2986 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec X,Vec F,void *ctx) 2987 { 2988 PetscErrorCode ierr; 2989 Mat Arhs,Brhs; 2990 MatStructure flg2; 2991 2992 PetscFunctionBegin; 2993 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 2994 ierr = TSComputeRHSJacobian(ts,t,X,&Arhs,&Brhs,&flg2);CHKERRQ(ierr); 2995 ierr = MatMult(Arhs,X,F);CHKERRQ(ierr); 2996 PetscFunctionReturn(0); 2997 } 2998 2999 #undef __FUNCT__ 3000 #define __FUNCT__ "TSComputeRHSJacobianConstant" 3001 /*@C 3002 TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent. 3003 3004 Collective on TS 3005 3006 Input Arguments: 3007 + ts - time stepping context 3008 . t - time at which to evaluate 3009 . X - state at which to evaluate 3010 - ctx - context 3011 3012 Output Arguments: 3013 + A - pointer to operator 3014 . B - pointer to preconditioning matrix 3015 - flg - matrix structure flag 3016 3017 Level: intermediate 3018 3019 Notes: 3020 This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems. 3021 3022 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear() 3023 @*/ 3024 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec X,Mat *A,Mat *B,MatStructure *flg,void *ctx) 3025 { 3026 3027 PetscFunctionBegin; 3028 *flg = SAME_PRECONDITIONER; 3029 PetscFunctionReturn(0); 3030 } 3031 3032 #undef __FUNCT__ 3033 #define __FUNCT__ "TSComputeIFunctionLinear" 3034 /*@C 3035 TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only 3036 3037 Collective on TS 3038 3039 Input Arguments: 3040 + ts - time stepping context 3041 . t - time at which to evaluate 3042 . X - state at which to evaluate 3043 . Xdot - time derivative of state vector 3044 - ctx - context 3045 3046 Output Arguments: 3047 . F - left hand side 3048 3049 Level: intermediate 3050 3051 Notes: 3052 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 3053 user is required to write their own TSComputeIFunction. 3054 This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems. 3055 The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian(). 3056 3057 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant() 3058 @*/ 3059 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec X,Vec Xdot,Vec F,void *ctx) 3060 { 3061 PetscErrorCode ierr; 3062 Mat A,B; 3063 MatStructure flg2; 3064 3065 PetscFunctionBegin; 3066 ierr = TSGetIJacobian(ts,&A,&B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 3067 ierr = TSComputeIJacobian(ts,t,X,Xdot,1.0,&A,&B,&flg2,PETSC_TRUE);CHKERRQ(ierr); 3068 ierr = MatMult(A,Xdot,F);CHKERRQ(ierr); 3069 PetscFunctionReturn(0); 3070 } 3071 3072 #undef __FUNCT__ 3073 #define __FUNCT__ "TSComputeIJacobianConstant" 3074 /*@C 3075 TSComputeIJacobianConstant - Reuses a Jacobian that is time-independent. 3076 3077 Collective on TS 3078 3079 Input Arguments: 3080 + ts - time stepping context 3081 . t - time at which to evaluate 3082 . X - state at which to evaluate 3083 . Xdot - time derivative of state vector 3084 . shift - shift to apply 3085 - ctx - context 3086 3087 Output Arguments: 3088 + A - pointer to operator 3089 . B - pointer to preconditioning matrix 3090 - flg - matrix structure flag 3091 3092 Level: intermediate 3093 3094 Notes: 3095 This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems. 3096 3097 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear() 3098 @*/ 3099 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec X,Vec Xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,void *ctx) 3100 { 3101 3102 PetscFunctionBegin; 3103 *flg = SAME_PRECONDITIONER; 3104 PetscFunctionReturn(0); 3105 } 3106 3107 3108 #undef __FUNCT__ 3109 #define __FUNCT__ "TSGetConvergedReason" 3110 /*@ 3111 TSGetConvergedReason - Gets the reason the TS iteration was stopped. 3112 3113 Not Collective 3114 3115 Input Parameter: 3116 . ts - the TS context 3117 3118 Output Parameter: 3119 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 3120 manual pages for the individual convergence tests for complete lists 3121 3122 Level: intermediate 3123 3124 Notes: 3125 Can only be called after the call to TSSolve() is complete. 3126 3127 .keywords: TS, nonlinear, set, convergence, test 3128 3129 .seealso: TSSetConvergenceTest(), TSConvergedReason 3130 @*/ 3131 PetscErrorCode TSGetConvergedReason(TS ts,TSConvergedReason *reason) 3132 { 3133 PetscFunctionBegin; 3134 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3135 PetscValidPointer(reason,2); 3136 *reason = ts->reason; 3137 PetscFunctionReturn(0); 3138 } 3139 3140 #undef __FUNCT__ 3141 #define __FUNCT__ "TSGetSNESIterations" 3142 /*@ 3143 TSGetSNESIterations - Gets the total number of nonlinear iterations 3144 used by the time integrator. 3145 3146 Not Collective 3147 3148 Input Parameter: 3149 . ts - TS context 3150 3151 Output Parameter: 3152 . nits - number of nonlinear iterations 3153 3154 Notes: 3155 This counter is reset to zero for each successive call to TSSolve(). 3156 3157 Level: intermediate 3158 3159 .keywords: TS, get, number, nonlinear, iterations 3160 3161 .seealso: TSGetKSPIterations() 3162 @*/ 3163 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits) 3164 { 3165 PetscFunctionBegin; 3166 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3167 PetscValidIntPointer(nits,2); 3168 *nits = ts->snes_its; 3169 PetscFunctionReturn(0); 3170 } 3171 3172 #undef __FUNCT__ 3173 #define __FUNCT__ "TSGetKSPIterations" 3174 /*@ 3175 TSGetKSPIterations - Gets the total number of linear iterations 3176 used by the time integrator. 3177 3178 Not Collective 3179 3180 Input Parameter: 3181 . ts - TS context 3182 3183 Output Parameter: 3184 . lits - number of linear iterations 3185 3186 Notes: 3187 This counter is reset to zero for each successive call to TSSolve(). 3188 3189 Level: intermediate 3190 3191 .keywords: TS, get, number, linear, iterations 3192 3193 .seealso: TSGetSNESIterations(), SNESGetKSPIterations() 3194 @*/ 3195 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits) 3196 { 3197 PetscFunctionBegin; 3198 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3199 PetscValidIntPointer(lits,2); 3200 *lits = ts->ksp_its; 3201 PetscFunctionReturn(0); 3202 } 3203 3204 #undef __FUNCT__ 3205 #define __FUNCT__ "TSGetStepRejections" 3206 /*@ 3207 TSGetStepRejections - Gets the total number of rejected steps. 3208 3209 Not Collective 3210 3211 Input Parameter: 3212 . ts - TS context 3213 3214 Output Parameter: 3215 . rejects - number of steps rejected 3216 3217 Notes: 3218 This counter is reset to zero for each successive call to TSSolve(). 3219 3220 Level: intermediate 3221 3222 .keywords: TS, get, number 3223 3224 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails() 3225 @*/ 3226 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects) 3227 { 3228 PetscFunctionBegin; 3229 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3230 PetscValidIntPointer(rejects,2); 3231 *rejects = ts->reject; 3232 PetscFunctionReturn(0); 3233 } 3234 3235 #undef __FUNCT__ 3236 #define __FUNCT__ "TSGetSNESFailures" 3237 /*@ 3238 TSGetSNESFailures - Gets the total number of failed SNES solves 3239 3240 Not Collective 3241 3242 Input Parameter: 3243 . ts - TS context 3244 3245 Output Parameter: 3246 . fails - number of failed nonlinear solves 3247 3248 Notes: 3249 This counter is reset to zero for each successive call to TSSolve(). 3250 3251 Level: intermediate 3252 3253 .keywords: TS, get, number 3254 3255 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures() 3256 @*/ 3257 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails) 3258 { 3259 PetscFunctionBegin; 3260 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3261 PetscValidIntPointer(fails,2); 3262 *fails = ts->num_snes_failures; 3263 PetscFunctionReturn(0); 3264 } 3265 3266 #undef __FUNCT__ 3267 #define __FUNCT__ "TSSetMaxStepRejections" 3268 /*@ 3269 TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails 3270 3271 Not Collective 3272 3273 Input Parameter: 3274 + ts - TS context 3275 - rejects - maximum number of rejected steps, pass -1 for unlimited 3276 3277 Notes: 3278 The counter is reset to zero for each step 3279 3280 Options Database Key: 3281 . -ts_max_reject - Maximum number of step rejections before a step fails 3282 3283 Level: intermediate 3284 3285 .keywords: TS, set, maximum, number 3286 3287 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 3288 @*/ 3289 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects) 3290 { 3291 PetscFunctionBegin; 3292 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3293 ts->max_reject = rejects; 3294 PetscFunctionReturn(0); 3295 } 3296 3297 #undef __FUNCT__ 3298 #define __FUNCT__ "TSSetMaxSNESFailures" 3299 /*@ 3300 TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves 3301 3302 Not Collective 3303 3304 Input Parameter: 3305 + ts - TS context 3306 - fails - maximum number of failed nonlinear solves, pass -1 for unlimited 3307 3308 Notes: 3309 The counter is reset to zero for each successive call to TSSolve(). 3310 3311 Options Database Key: 3312 . -ts_max_snes_failures - Maximum number of nonlinear solve failures 3313 3314 Level: intermediate 3315 3316 .keywords: TS, set, maximum, number 3317 3318 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason() 3319 @*/ 3320 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails) 3321 { 3322 PetscFunctionBegin; 3323 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3324 ts->max_snes_failures = fails; 3325 PetscFunctionReturn(0); 3326 } 3327 3328 #undef __FUNCT__ 3329 #define __FUNCT__ "TSSetErrorIfStepFails()" 3330 /*@ 3331 TSSetErrorIfStepFails - Error if no step succeeds 3332 3333 Not Collective 3334 3335 Input Parameter: 3336 + ts - TS context 3337 - err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure 3338 3339 Options Database Key: 3340 . -ts_error_if_step_fails - Error if no step succeeds 3341 3342 Level: intermediate 3343 3344 .keywords: TS, set, error 3345 3346 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 3347 @*/ 3348 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err) 3349 { 3350 PetscFunctionBegin; 3351 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3352 ts->errorifstepfailed = err; 3353 PetscFunctionReturn(0); 3354 } 3355 3356 #undef __FUNCT__ 3357 #define __FUNCT__ "TSMonitorSolutionBinary" 3358 /*@C 3359 TSMonitorSolutionBinary - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file 3360 3361 Collective on TS 3362 3363 Input Parameters: 3364 + ts - the TS context 3365 . step - current time-step 3366 . ptime - current time 3367 . x - current state 3368 - viewer - binary viewer 3369 3370 Level: intermediate 3371 3372 .keywords: TS, vector, monitor, view 3373 3374 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 3375 @*/ 3376 PetscErrorCode TSMonitorSolutionBinary(TS ts,PetscInt step,PetscReal ptime,Vec x,void *viewer) 3377 { 3378 PetscErrorCode ierr; 3379 PetscViewer v = (PetscViewer)viewer; 3380 3381 PetscFunctionBegin; 3382 ierr = VecView(x,v);CHKERRQ(ierr); 3383 PetscFunctionReturn(0); 3384 } 3385 3386 #undef __FUNCT__ 3387 #define __FUNCT__ "TSMonitorSolutionVTK" 3388 /*@C 3389 TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep. 3390 3391 Collective on TS 3392 3393 Input Parameters: 3394 + ts - the TS context 3395 . step - current time-step 3396 . ptime - current time 3397 . x - current state 3398 - filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 3399 3400 Level: intermediate 3401 3402 Notes: 3403 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. 3404 These are named according to the file name template. 3405 3406 This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy(). 3407 3408 .keywords: TS, vector, monitor, view 3409 3410 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 3411 @*/ 3412 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec x,void *filenametemplate) 3413 { 3414 PetscErrorCode ierr; 3415 char filename[PETSC_MAX_PATH_LEN]; 3416 PetscViewer viewer; 3417 3418 PetscFunctionBegin; 3419 ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr); 3420 ierr = PetscViewerVTKOpen(((PetscObject)ts)->comm,filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); 3421 ierr = VecView(x,viewer);CHKERRQ(ierr); 3422 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3423 PetscFunctionReturn(0); 3424 } 3425 3426 #undef __FUNCT__ 3427 #define __FUNCT__ "TSMonitorSolutionVTKDestroy" 3428 /*@C 3429 TSMonitorSolutionVTKDestroy - Destroy context for monitoring 3430 3431 Collective on TS 3432 3433 Input Parameters: 3434 . filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 3435 3436 Level: intermediate 3437 3438 Note: 3439 This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK(). 3440 3441 .keywords: TS, vector, monitor, view 3442 3443 .seealso: TSMonitorSet(), TSMonitorSolutionVTK() 3444 @*/ 3445 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate) 3446 { 3447 PetscErrorCode ierr; 3448 3449 PetscFunctionBegin; 3450 ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr); 3451 PetscFunctionReturn(0); 3452 } 3453 3454 #undef __FUNCT__ 3455 #define __FUNCT__ "TSGetAdapt" 3456 /*@ 3457 TSGetAdapt - Get the adaptive controller context for the current method 3458 3459 Collective on TS if controller has not been created yet 3460 3461 Input Arguments: 3462 . ts - time stepping context 3463 3464 Output Arguments: 3465 . adapt - adaptive controller 3466 3467 Level: intermediate 3468 3469 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose() 3470 @*/ 3471 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt) 3472 { 3473 PetscErrorCode ierr; 3474 3475 PetscFunctionBegin; 3476 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3477 PetscValidPointer(adapt,2); 3478 if (!ts->adapt) { 3479 ierr = TSAdaptCreate(((PetscObject)ts)->comm,&ts->adapt);CHKERRQ(ierr); 3480 ierr = PetscLogObjectParent(ts,ts->adapt);CHKERRQ(ierr); 3481 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr); 3482 } 3483 *adapt = ts->adapt; 3484 PetscFunctionReturn(0); 3485 } 3486 3487 #undef __FUNCT__ 3488 #define __FUNCT__ "TSSetTolerances" 3489 /*@ 3490 TSSetTolerances - Set tolerances for local truncation error when using adaptive controller 3491 3492 Logically Collective 3493 3494 Input Arguments: 3495 + ts - time integration context 3496 . atol - scalar absolute tolerances, PETSC_DECIDE to leave current value 3497 . vatol - vector of absolute tolerances or PETSC_NULL, used in preference to atol if present 3498 . rtol - scalar relative tolerances, PETSC_DECIDE to leave current value 3499 - vrtol - vector of relative tolerances or PETSC_NULL, used in preference to atol if present 3500 3501 Level: beginner 3502 3503 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances() 3504 @*/ 3505 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol) 3506 { 3507 PetscErrorCode ierr; 3508 3509 PetscFunctionBegin; 3510 if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol; 3511 if (vatol) { 3512 ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr); 3513 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 3514 ts->vatol = vatol; 3515 } 3516 if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol; 3517 if (vrtol) { 3518 ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr); 3519 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 3520 ts->vrtol = vrtol; 3521 } 3522 PetscFunctionReturn(0); 3523 } 3524 3525 #undef __FUNCT__ 3526 #define __FUNCT__ "TSGetTolerances" 3527 /*@ 3528 TSGetTolerances - Get tolerances for local truncation error when using adaptive controller 3529 3530 Logically Collective 3531 3532 Input Arguments: 3533 . ts - time integration context 3534 3535 Output Arguments: 3536 + atol - scalar absolute tolerances, PETSC_NULL to ignore 3537 . vatol - vector of absolute tolerances, PETSC_NULL to ignore 3538 . rtol - scalar relative tolerances, PETSC_NULL to ignore 3539 - vrtol - vector of relative tolerances, PETSC_NULL to ignore 3540 3541 Level: beginner 3542 3543 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances() 3544 @*/ 3545 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol) 3546 { 3547 3548 PetscFunctionBegin; 3549 if (atol) *atol = ts->atol; 3550 if (vatol) *vatol = ts->vatol; 3551 if (rtol) *rtol = ts->rtol; 3552 if (vrtol) *vrtol = ts->vrtol; 3553 PetscFunctionReturn(0); 3554 } 3555 3556 #undef __FUNCT__ 3557 #define __FUNCT__ "TSErrorNormWRMS" 3558 /*@ 3559 TSErrorNormWRMS - compute a weighted norm of the difference between a vector and the current state 3560 3561 Collective on TS 3562 3563 Input Arguments: 3564 + ts - time stepping context 3565 - Y - state vector to be compared to ts->vec_sol 3566 3567 Output Arguments: 3568 . norm - weighted norm, a value of 1.0 is considered small 3569 3570 Level: developer 3571 3572 .seealso: TSSetTolerances() 3573 @*/ 3574 PetscErrorCode TSErrorNormWRMS(TS ts,Vec Y,PetscReal *norm) 3575 { 3576 PetscErrorCode ierr; 3577 PetscInt i,n,N; 3578 const PetscScalar *x,*y; 3579 Vec X; 3580 PetscReal sum,gsum; 3581 3582 PetscFunctionBegin; 3583 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3584 PetscValidHeaderSpecific(Y,VEC_CLASSID,2); 3585 PetscValidPointer(norm,3); 3586 X = ts->vec_sol; 3587 PetscCheckSameTypeAndComm(X,1,Y,2); 3588 if (X == Y) SETERRQ(((PetscObject)X)->comm,PETSC_ERR_ARG_IDN,"Y cannot be the TS solution vector"); 3589 3590 ierr = VecGetSize(X,&N);CHKERRQ(ierr); 3591 ierr = VecGetLocalSize(X,&n);CHKERRQ(ierr); 3592 ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr); 3593 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 3594 sum = 0.; 3595 if (ts->vatol && ts->vrtol) { 3596 const PetscScalar *atol,*rtol; 3597 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 3598 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 3599 for (i=0; i<n; i++) { 3600 PetscReal tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(x[i]),PetscAbsScalar(y[i])); 3601 sum += PetscSqr(PetscAbsScalar(y[i] - x[i]) / tol); 3602 } 3603 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 3604 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 3605 } else if (ts->vatol) { /* vector atol, scalar rtol */ 3606 const PetscScalar *atol; 3607 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 3608 for (i=0; i<n; i++) { 3609 PetscReal tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(x[i]),PetscAbsScalar(y[i])); 3610 sum += PetscSqr(PetscAbsScalar(y[i] - x[i]) / tol); 3611 } 3612 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 3613 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 3614 const PetscScalar *rtol; 3615 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 3616 for (i=0; i<n; i++) { 3617 PetscReal tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(x[i]),PetscAbsScalar(y[i])); 3618 sum += PetscSqr(PetscAbsScalar(y[i] - x[i]) / tol); 3619 } 3620 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 3621 } else { /* scalar atol, scalar rtol */ 3622 for (i=0; i<n; i++) { 3623 PetscReal tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(x[i]),PetscAbsScalar(y[i])); 3624 sum += PetscSqr(PetscAbsScalar(y[i] - x[i]) / tol); 3625 } 3626 } 3627 ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr); 3628 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 3629 3630 ierr = MPI_Allreduce(&sum,&gsum,1,MPIU_REAL,MPIU_SUM,((PetscObject)ts)->comm);CHKERRQ(ierr); 3631 *norm = PetscSqrtReal(gsum / N); 3632 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 3633 PetscFunctionReturn(0); 3634 } 3635 3636 #undef __FUNCT__ 3637 #define __FUNCT__ "TSSetCFLTimeLocal" 3638 /*@ 3639 TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler 3640 3641 Logically Collective on TS 3642 3643 Input Arguments: 3644 + ts - time stepping context 3645 - cfltime - maximum stable time step if using forward Euler (value can be different on each process) 3646 3647 Note: 3648 After calling this function, the global CFL time can be obtained by calling TSGetCFLTime() 3649 3650 Level: intermediate 3651 3652 .seealso: TSGetCFLTime(), TSADAPTCFL 3653 @*/ 3654 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime) 3655 { 3656 3657 PetscFunctionBegin; 3658 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3659 ts->cfltime_local = cfltime; 3660 ts->cfltime = -1.; 3661 PetscFunctionReturn(0); 3662 } 3663 3664 #undef __FUNCT__ 3665 #define __FUNCT__ "TSGetCFLTime" 3666 /*@ 3667 TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler 3668 3669 Collective on TS 3670 3671 Input Arguments: 3672 . ts - time stepping context 3673 3674 Output Arguments: 3675 . cfltime - maximum stable time step for forward Euler 3676 3677 Level: advanced 3678 3679 .seealso: TSSetCFLTimeLocal() 3680 @*/ 3681 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime) 3682 { 3683 PetscErrorCode ierr; 3684 3685 PetscFunctionBegin; 3686 if (ts->cfltime < 0) { 3687 ierr = MPI_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,((PetscObject)ts)->comm);CHKERRQ(ierr); 3688 } 3689 *cfltime = ts->cfltime; 3690 PetscFunctionReturn(0); 3691 } 3692 3693 #undef __FUNCT__ 3694 #define __FUNCT__ "TSVISetVariableBounds" 3695 /*@ 3696 TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu 3697 3698 Input Parameters: 3699 . ts - the TS context. 3700 . xl - lower bound. 3701 . xu - upper bound. 3702 3703 Notes: 3704 If this routine is not called then the lower and upper bounds are set to 3705 SNES_VI_NINF and SNES_VI_INF respectively during SNESSetUp(). 3706 3707 Level: advanced 3708 3709 @*/ 3710 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu) 3711 { 3712 PetscErrorCode ierr; 3713 SNES snes; 3714 3715 PetscFunctionBegin; 3716 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 3717 ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr); 3718 PetscFunctionReturn(0); 3719 } 3720 3721 #if defined(PETSC_HAVE_MATLAB_ENGINE) 3722 #include <mex.h> 3723 3724 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext; 3725 3726 #undef __FUNCT__ 3727 #define __FUNCT__ "TSComputeFunction_Matlab" 3728 /* 3729 TSComputeFunction_Matlab - Calls the function that has been set with 3730 TSSetFunctionMatlab(). 3731 3732 Collective on TS 3733 3734 Input Parameters: 3735 + snes - the TS context 3736 - x - input vector 3737 3738 Output Parameter: 3739 . y - function vector, as set by TSSetFunction() 3740 3741 Notes: 3742 TSComputeFunction() is typically used within nonlinear solvers 3743 implementations, so most users would not generally call this routine 3744 themselves. 3745 3746 Level: developer 3747 3748 .keywords: TS, nonlinear, compute, function 3749 3750 .seealso: TSSetFunction(), TSGetFunction() 3751 */ 3752 PetscErrorCode TSComputeFunction_Matlab(TS snes,PetscReal time,Vec x,Vec xdot,Vec y, void *ctx) 3753 { 3754 PetscErrorCode ierr; 3755 TSMatlabContext *sctx = (TSMatlabContext *)ctx; 3756 int nlhs = 1,nrhs = 7; 3757 mxArray *plhs[1],*prhs[7]; 3758 long long int lx = 0,lxdot = 0,ly = 0,ls = 0; 3759 3760 PetscFunctionBegin; 3761 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 3762 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3763 PetscValidHeaderSpecific(xdot,VEC_CLASSID,4); 3764 PetscValidHeaderSpecific(y,VEC_CLASSID,5); 3765 PetscCheckSameComm(snes,1,x,3); 3766 PetscCheckSameComm(snes,1,y,5); 3767 3768 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3769 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3770 ierr = PetscMemcpy(&lxdot,&xdot,sizeof(xdot));CHKERRQ(ierr); 3771 ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 3772 prhs[0] = mxCreateDoubleScalar((double)ls); 3773 prhs[1] = mxCreateDoubleScalar(time); 3774 prhs[2] = mxCreateDoubleScalar((double)lx); 3775 prhs[3] = mxCreateDoubleScalar((double)lxdot); 3776 prhs[4] = mxCreateDoubleScalar((double)ly); 3777 prhs[5] = mxCreateString(sctx->funcname); 3778 prhs[6] = sctx->ctx; 3779 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr); 3780 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3781 mxDestroyArray(prhs[0]); 3782 mxDestroyArray(prhs[1]); 3783 mxDestroyArray(prhs[2]); 3784 mxDestroyArray(prhs[3]); 3785 mxDestroyArray(prhs[4]); 3786 mxDestroyArray(prhs[5]); 3787 mxDestroyArray(plhs[0]); 3788 PetscFunctionReturn(0); 3789 } 3790 3791 3792 #undef __FUNCT__ 3793 #define __FUNCT__ "TSSetFunctionMatlab" 3794 /* 3795 TSSetFunctionMatlab - Sets the function evaluation routine and function 3796 vector for use by the TS routines in solving ODEs 3797 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 3798 3799 Logically Collective on TS 3800 3801 Input Parameters: 3802 + ts - the TS context 3803 - func - function evaluation routine 3804 3805 Calling sequence of func: 3806 $ func (TS ts,PetscReal time,Vec x,Vec xdot,Vec f,void *ctx); 3807 3808 Level: beginner 3809 3810 .keywords: TS, nonlinear, set, function 3811 3812 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 3813 */ 3814 PetscErrorCode TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx) 3815 { 3816 PetscErrorCode ierr; 3817 TSMatlabContext *sctx; 3818 3819 PetscFunctionBegin; 3820 /* currently sctx is memory bleed */ 3821 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 3822 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3823 /* 3824 This should work, but it doesn't 3825 sctx->ctx = ctx; 3826 mexMakeArrayPersistent(sctx->ctx); 3827 */ 3828 sctx->ctx = mxDuplicateArray(ctx); 3829 ierr = TSSetIFunction(ts,PETSC_NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr); 3830 PetscFunctionReturn(0); 3831 } 3832 3833 #undef __FUNCT__ 3834 #define __FUNCT__ "TSComputeJacobian_Matlab" 3835 /* 3836 TSComputeJacobian_Matlab - Calls the function that has been set with 3837 TSSetJacobianMatlab(). 3838 3839 Collective on TS 3840 3841 Input Parameters: 3842 + ts - the TS context 3843 . x - input vector 3844 . A, B - the matrices 3845 - ctx - user context 3846 3847 Output Parameter: 3848 . flag - structure of the matrix 3849 3850 Level: developer 3851 3852 .keywords: TS, nonlinear, compute, function 3853 3854 .seealso: TSSetFunction(), TSGetFunction() 3855 @*/ 3856 PetscErrorCode TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec x,Vec xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flag, void *ctx) 3857 { 3858 PetscErrorCode ierr; 3859 TSMatlabContext *sctx = (TSMatlabContext *)ctx; 3860 int nlhs = 2,nrhs = 9; 3861 mxArray *plhs[2],*prhs[9]; 3862 long long int lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0; 3863 3864 PetscFunctionBegin; 3865 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3866 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3867 3868 /* call Matlab function in ctx with arguments x and y */ 3869 3870 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 3871 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3872 ierr = PetscMemcpy(&lxdot,&xdot,sizeof(x));CHKERRQ(ierr); 3873 ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 3874 ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 3875 prhs[0] = mxCreateDoubleScalar((double)ls); 3876 prhs[1] = mxCreateDoubleScalar((double)time); 3877 prhs[2] = mxCreateDoubleScalar((double)lx); 3878 prhs[3] = mxCreateDoubleScalar((double)lxdot); 3879 prhs[4] = mxCreateDoubleScalar((double)shift); 3880 prhs[5] = mxCreateDoubleScalar((double)lA); 3881 prhs[6] = mxCreateDoubleScalar((double)lB); 3882 prhs[7] = mxCreateString(sctx->funcname); 3883 prhs[8] = sctx->ctx; 3884 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr); 3885 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3886 *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 3887 mxDestroyArray(prhs[0]); 3888 mxDestroyArray(prhs[1]); 3889 mxDestroyArray(prhs[2]); 3890 mxDestroyArray(prhs[3]); 3891 mxDestroyArray(prhs[4]); 3892 mxDestroyArray(prhs[5]); 3893 mxDestroyArray(prhs[6]); 3894 mxDestroyArray(prhs[7]); 3895 mxDestroyArray(plhs[0]); 3896 mxDestroyArray(plhs[1]); 3897 PetscFunctionReturn(0); 3898 } 3899 3900 3901 #undef __FUNCT__ 3902 #define __FUNCT__ "TSSetJacobianMatlab" 3903 /* 3904 TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 3905 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 3906 3907 Logically Collective on TS 3908 3909 Input Parameters: 3910 + ts - the TS context 3911 . A,B - Jacobian matrices 3912 . func - function evaluation routine 3913 - ctx - user context 3914 3915 Calling sequence of func: 3916 $ flag = func (TS ts,PetscReal time,Vec x,Vec xdot,Mat A,Mat B,void *ctx); 3917 3918 3919 Level: developer 3920 3921 .keywords: TS, nonlinear, set, function 3922 3923 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 3924 */ 3925 PetscErrorCode TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx) 3926 { 3927 PetscErrorCode ierr; 3928 TSMatlabContext *sctx; 3929 3930 PetscFunctionBegin; 3931 /* currently sctx is memory bleed */ 3932 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 3933 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3934 /* 3935 This should work, but it doesn't 3936 sctx->ctx = ctx; 3937 mexMakeArrayPersistent(sctx->ctx); 3938 */ 3939 sctx->ctx = mxDuplicateArray(ctx); 3940 ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 3941 PetscFunctionReturn(0); 3942 } 3943 3944 #undef __FUNCT__ 3945 #define __FUNCT__ "TSMonitor_Matlab" 3946 /* 3947 TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab(). 3948 3949 Collective on TS 3950 3951 .seealso: TSSetFunction(), TSGetFunction() 3952 @*/ 3953 PetscErrorCode TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec x, void *ctx) 3954 { 3955 PetscErrorCode ierr; 3956 TSMatlabContext *sctx = (TSMatlabContext *)ctx; 3957 int nlhs = 1,nrhs = 6; 3958 mxArray *plhs[1],*prhs[6]; 3959 long long int lx = 0,ls = 0; 3960 3961 PetscFunctionBegin; 3962 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3963 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3964 3965 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 3966 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3967 prhs[0] = mxCreateDoubleScalar((double)ls); 3968 prhs[1] = mxCreateDoubleScalar((double)it); 3969 prhs[2] = mxCreateDoubleScalar((double)time); 3970 prhs[3] = mxCreateDoubleScalar((double)lx); 3971 prhs[4] = mxCreateString(sctx->funcname); 3972 prhs[5] = sctx->ctx; 3973 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr); 3974 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3975 mxDestroyArray(prhs[0]); 3976 mxDestroyArray(prhs[1]); 3977 mxDestroyArray(prhs[2]); 3978 mxDestroyArray(prhs[3]); 3979 mxDestroyArray(prhs[4]); 3980 mxDestroyArray(plhs[0]); 3981 PetscFunctionReturn(0); 3982 } 3983 3984 3985 #undef __FUNCT__ 3986 #define __FUNCT__ "TSMonitorSetMatlab" 3987 /* 3988 TSMonitorSetMatlab - Sets the monitor function from Matlab 3989 3990 Level: developer 3991 3992 .keywords: TS, nonlinear, set, function 3993 3994 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 3995 */ 3996 PetscErrorCode TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx) 3997 { 3998 PetscErrorCode ierr; 3999 TSMatlabContext *sctx; 4000 4001 PetscFunctionBegin; 4002 /* currently sctx is memory bleed */ 4003 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 4004 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4005 /* 4006 This should work, but it doesn't 4007 sctx->ctx = ctx; 4008 mexMakeArrayPersistent(sctx->ctx); 4009 */ 4010 sctx->ctx = mxDuplicateArray(ctx); 4011 ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4012 PetscFunctionReturn(0); 4013 } 4014 #endif 4015 4016 4017 4018 #undef __FUNCT__ 4019 #define __FUNCT__ "TSMonitorLGSolution" 4020 /*@C 4021 TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector 4022 in a time based line graph 4023 4024 Collective on TS 4025 4026 Input Parameters: 4027 + ts - the TS context 4028 . step - current time-step 4029 . ptime - current time 4030 - lg - a line graph object 4031 4032 Level: intermediate 4033 4034 Notes: each process in a parallel run displays its component solutions in a separate window 4035 4036 .keywords: TS, vector, monitor, view 4037 4038 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4039 @*/ 4040 PetscErrorCode TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec x,void *dummy) 4041 { 4042 PetscErrorCode ierr; 4043 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 4044 const PetscScalar *yy; 4045 PetscInt dim; 4046 4047 PetscFunctionBegin; 4048 if (!step) { 4049 PetscDrawAxis axis; 4050 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 4051 ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr); 4052 ierr = VecGetLocalSize(x,&dim);CHKERRQ(ierr); 4053 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 4054 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 4055 } 4056 ierr = VecGetArrayRead(x,&yy);CHKERRQ(ierr); 4057 #if defined(PETSC_USE_COMPLEX) 4058 { 4059 PetscReal *yreal; 4060 PetscInt i,n; 4061 ierr = VecGetLocalSize(x,&n);CHKERRQ(ierr); 4062 ierr = PetscMalloc(n*sizeof(PetscReal),&yreal);CHKERRQ(ierr); 4063 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 4064 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 4065 ierr = PetscFree(yreal);CHKERRQ(ierr); 4066 } 4067 #else 4068 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 4069 #endif 4070 ierr = VecRestoreArrayRead(x,&yy);CHKERRQ(ierr); 4071 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && (step == -1))){ 4072 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 4073 } 4074 PetscFunctionReturn(0); 4075 } 4076 4077 #undef __FUNCT__ 4078 #define __FUNCT__ "TSMonitorLGError" 4079 /*@C 4080 TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the solution vector 4081 in a time based line graph 4082 4083 Collective on TS 4084 4085 Input Parameters: 4086 + ts - the TS context 4087 . step - current time-step 4088 . ptime - current time 4089 - lg - a line graph object 4090 4091 Level: intermediate 4092 4093 Notes: 4094 Only for sequential solves. 4095 4096 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 4097 4098 Options Database Keys: 4099 . -ts_monitor_lg_error - create a graphical monitor of error history 4100 4101 .keywords: TS, vector, monitor, view 4102 4103 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 4104 @*/ 4105 PetscErrorCode TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec x,void *dummy) 4106 { 4107 PetscErrorCode ierr; 4108 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 4109 const PetscScalar *yy; 4110 Vec y; 4111 PetscInt dim; 4112 4113 PetscFunctionBegin; 4114 if (!step) { 4115 PetscDrawAxis axis; 4116 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 4117 ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr); 4118 ierr = VecGetLocalSize(x,&dim);CHKERRQ(ierr); 4119 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 4120 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 4121 } 4122 ierr = VecDuplicate(x,&y);CHKERRQ(ierr); 4123 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 4124 ierr = VecAXPY(y,-1.0,x);CHKERRQ(ierr); 4125 ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr); 4126 #if defined(PETSC_USE_COMPLEX) 4127 { 4128 PetscReal *yreal; 4129 PetscInt i,n; 4130 ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr); 4131 ierr = PetscMalloc(n*sizeof(PetscReal),&yreal);CHKERRQ(ierr); 4132 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 4133 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 4134 ierr = PetscFree(yreal);CHKERRQ(ierr); 4135 } 4136 #else 4137 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 4138 #endif 4139 ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr); 4140 ierr = VecDestroy(&y);CHKERRQ(ierr); 4141 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && (step == -1))){ 4142 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 4143 } 4144 PetscFunctionReturn(0); 4145 } 4146 4147 #undef __FUNCT__ 4148 #define __FUNCT__ "TSMonitorLGSNESIterations" 4149 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 4150 { 4151 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 4152 PetscReal x = ptime,y; 4153 PetscErrorCode ierr; 4154 PetscInt its; 4155 4156 PetscFunctionBegin; 4157 if (!n) { 4158 PetscDrawAxis axis; 4159 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 4160 ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr); 4161 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 4162 ctx->snes_its = 0; 4163 } 4164 ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr); 4165 y = its - ctx->snes_its; 4166 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 4167 if (((ctx->howoften > 0) && (!(n % ctx->howoften))) || ((ctx->howoften == -1) && (n == -1))){ 4168 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 4169 } 4170 ctx->snes_its = its; 4171 PetscFunctionReturn(0); 4172 } 4173 4174 #undef __FUNCT__ 4175 #define __FUNCT__ "TSMonitorLGKSPIterations" 4176 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 4177 { 4178 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 4179 PetscReal x = ptime,y; 4180 PetscErrorCode ierr; 4181 PetscInt its; 4182 4183 PetscFunctionBegin; 4184 if (!n) { 4185 PetscDrawAxis axis; 4186 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 4187 ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr); 4188 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 4189 ctx->ksp_its = 0; 4190 } 4191 ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr); 4192 y = its - ctx->ksp_its; 4193 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 4194 if (((ctx->howoften > 0) && (!(n % ctx->howoften))) || ((ctx->howoften == -1) && (n == -1))){ 4195 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 4196 } 4197 ctx->ksp_its = its; 4198 PetscFunctionReturn(0); 4199 } 4200