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