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