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