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