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