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